@Override public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) { final boolean isPrimaryUser = Process.myUserHandle().equals(user); if (!isPrimaryUser && (flags == 0)) { // We are looking for an installed app on a secondary profile. Prior to O, the only // entry point for work profiles is through the LauncherActivity. List<LauncherActivityInfo> activityList = mLauncherApps.getActivityList(packageName, user); return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null; } try { ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName, flags); // There is no way to check if the app is installed for managed profile. But for // primary profile, we can still have this check. if (isPrimaryUser && ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) || !info.enabled) { return null; } return info; } catch (PackageManager.NameNotFoundException e) { // Package not found return null; } }
@Override public boolean startConfigActivity(Activity activity, int requestCode) { if (getUser().equals(Process.myUserHandle())) { return super.startConfigActivity(activity, requestCode); } try { Method m = LauncherApps.class.getDeclaredMethod( "getShortcutConfigActivityIntent", LauncherActivityInfo.class); IntentSender is = (IntentSender) m.invoke( activity.getSystemService(LauncherApps.class), mInfo); activity.startIntentSenderForResult(is, requestCode, null, 0, 0, 0); return true; } catch (Exception e) { e.printStackTrace(); return false; } }
@Override public void onPackageAdded(String packageName, UserHandle user) { String prefKey = INSTALLED_PACKAGES_PREFIX + mUserManager.getSerialNumberForUser(user); HashSet<String> packageSet = new HashSet<>(); final boolean userAppsExisted = getUserApps(packageSet, prefKey); if (!packageSet.contains(packageName)) { List<LauncherActivityInfo> activities = mLauncherApps.getActivityList(packageName, user); if (!activities.isEmpty()) { LauncherActivityInfo activityInfo = activities.get(0); packageSet.add(packageName); mPrefs.edit().putStringSet(prefKey, packageSet).apply(); onLauncherAppsAdded(Arrays.asList( new LauncherActivityInstallInfo(activityInfo, System.currentTimeMillis())), user, userAppsExisted); } } }
/** * Updates the entries related to the given package in memory and persistent DB. */ public synchronized void updateIconsForPkg(String packageName, UserHandle user) { removeIconsForPkg(packageName, user); try { int uninstalled = android.os.Build.VERSION.SDK_INT >= 24 ? PackageManager.MATCH_UNINSTALLED_PACKAGES : PackageManager.GET_UNINSTALLED_PACKAGES; PackageInfo info = mPackageManager.getPackageInfo(packageName, uninstalled); long userSerial = mUserManager.getSerialNumberForUser(user); for (LauncherActivityInfo app : mLauncherApps.getActivityList(packageName, user)) { addIconToDBAndMemCache(app, info, userSerial, false /*replace existing*/); } } catch (NameNotFoundException e) { e.printStackTrace(); return; } }
public void updateDbIcons(Set<String> ignorePackagesForMainUser) { // Remove all active icon update tasks. mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN); mIconProvider.updateSystemStateString(); for (UserHandle user : mUserManager.getUserProfiles()) { // Query for the set of apps final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user); // Fail if we don't have any apps // TODO: Fix this. Only fail for the current user. if (apps == null || apps.isEmpty()) { return; } // Update icon cache. This happens in segments and {@link #onPackageIconsUpdated} // is called by the icon cache when the job is complete. updateDBIcons(user, apps, Process.myUserHandle().equals(user) ? ignorePackagesForMainUser : Collections.<String>emptySet()); } }
/** * Adds an entry into the DB and the in-memory cache. * @param replaceExisting if true, it will recreate the bitmap even if it already exists in * the memory. This is useful then the previous bitmap was created using * old data. */ @Thunk private synchronized void addIconToDBAndMemCache(LauncherActivityInfo app, PackageInfo info, long userSerial, boolean replaceExisting) { final ComponentKey key = new ComponentKey(app.getComponentName(), app.getUser()); CacheEntry entry = null; if (!replaceExisting) { entry = mCache.get(key); // We can't reuse the entry if the high-res icon is not present. if (entry == null || entry.isLowResIcon || entry.icon == null) { entry = null; } } if (entry == null) { entry = new CacheEntry(); entry.icon = LauncherIcons.createBadgedIconBitmap(getFullResIcon(app), app.getUser(), mContext, app.getApplicationInfo().targetSdkVersion); } entry.title = app.getLabel(); entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser()); mCache.put(key, entry); Bitmap lowResIcon = generateLowResIcon(entry.icon, mActivityBgColor); ContentValues values = newContentValues(entry.icon, lowResIcon, entry.title.toString(), app.getApplicationInfo().packageName); addIconToDB(values, app.getComponentName(), info, userSerial); }
/** * Tries to create a new PendingInstallShortcutInfo which represents the same target, * but is an app target and not a shortcut. * @return the newly created info or the original one. */ private static PendingInstallShortcutInfo convertToLauncherActivityIfPossible( PendingInstallShortcutInfo original) { if (original.isLauncherActivity()) { // Already an activity target return original; } if (!Utilities.isLauncherAppTarget(original.launchIntent)) { return original; } LauncherActivityInfo info = LauncherAppsCompat.getInstance(original.mContext) .resolveActivity(original.launchIntent, original.user); if (info == null) { return original; } // Ignore any conflicts in the label name, as that can change based on locale. return new PendingInstallShortcutInfo(info, original.mContext); }
@Override public View getView(int position, View convertView, ViewGroup viewGroup) { ViewHolder holder = new ViewHolder(); if(convertView == null) { convertView = mInflater.inflate(R.layout.app_list_item,null, false); holder.icon = (ImageView)convertView.findViewById(R.id.icon); holder.lable = (TextView)convertView.findViewById(R.id.label); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } LauncherActivityInfo appInfo = mData.get(position); holder.icon.setImageDrawable(appInfo.getIcon(0)); holder.lable.setText(appInfo.getLabel()); return convertView; }
@Override public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList( @Nullable PackageUserKey packageUser) { List<ShortcutConfigActivityInfo> result = new ArrayList<>(); UserHandle myUser = Process.myUserHandle(); try { Method m = LauncherApps.class.getDeclaredMethod("getShortcutConfigActivityList", String.class, UserHandle.class); final List<UserHandle> users; final String packageName; if (packageUser == null) { users = UserManagerCompat.getInstance(mContext).getUserProfiles(); packageName = null; } else { users = new ArrayList<>(1); users.add(packageUser.mUser); packageName = packageUser.mPackageName; } for (UserHandle user : users) { boolean ignoreTargetSdk = myUser.equals(user); List<LauncherActivityInfo> activities = (List<LauncherActivityInfo>) m.invoke(mLauncherApps, packageName, user); for (LauncherActivityInfo activityInfo : activities) { if (ignoreTargetSdk || activityInfo.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) { result.add(new ShortcutConfigActivityInfoVO(activityInfo)); } } } } catch (Exception e) { e.printStackTrace(); } return result; }
/** * Make an ShortcutInfo object for a shortcut that is an application. */ public ShortcutInfo getAppShortcutInfo( Intent intent, boolean allowMissingTarget, boolean useLowResIcon) { if (user == null) { return null; } ComponentName componentName = intent.getComponent(); if (componentName == null) { return null; } Intent newIntent = new Intent(Intent.ACTION_MAIN, null); newIntent.addCategory(Intent.CATEGORY_LAUNCHER); newIntent.setComponent(componentName); LauncherActivityInfo lai = LauncherAppsCompat.getInstance(mContext) .resolveActivity(newIntent, user); if ((lai == null) && !allowMissingTarget) { return null; } final ShortcutInfo info = new ShortcutInfo(); info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; info.user = user; info.intent = newIntent; mIconCache.getTitleAndIcon(info, lai, useLowResIcon); if (mIconCache.isDefaultIcon(info.iconBitmap, user)) { Bitmap icon = loadIcon(info); info.iconBitmap = icon != null ? icon : info.iconBitmap; } if (lai != null && PackageManagerHelper.isAppSuspended(lai.getApplicationInfo())) { info.isDisabled = ShortcutInfo.FLAG_DISABLED_SUSPENDED; } // from the db if (TextUtils.isEmpty(info.title)) { info.title = getTitle(); } // fall back to the class name of the activity if (info.title == null) { info.title = componentName.getClassName(); } info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); return info; }
/** * Add the supplied ApplicationInfo objects to the list, and enqueue it into the * list to broadcast when notify() is called. * * If the app is already in the list, doesn't add it. */ public void add(AppInfo info, LauncherActivityInfo activityInfo) { if (!mAppFilter.shouldShowApp(info.componentName.getPackageName(), mContext)) { return; } if (findActivity(data, info.componentName, info.user)) { return; } mIconCache.getTitleAndIcon(info, activityInfo, true /* useLowResIcon */); data.add(info); added.add(info); }
/** * Add the icons for the supplied apk called packageName. */ public void addPackage(Context context, String packageName, UserHandle user) { final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); final List<LauncherActivityInfo> matches = launcherApps.getActivityList(packageName, user); for (LauncherActivityInfo info : matches) { add(new AppInfo(context, info, user), info); } }
/** * Returns whether <em>apps</em> contains <em>component</em>. */ private static boolean findActivity(List<LauncherActivityInfo> apps, ComponentName component) { for (LauncherActivityInfo info : apps) { if (info.getComponentName().equals(component)) { return true; } } return false; }
private void scheduleManagedHeuristicRunnable(final ManagedProfileHeuristic heuristic, final UserHandle user, final List<LauncherActivityInfo> apps) { if (heuristic != null) { // Assume the app lists now is updated. mIsManagedHeuristicAppsUpdated = false; final Runnable managedHeuristicRunnable = new Runnable() { @Override public void run() { if (mIsManagedHeuristicAppsUpdated) { // If app list is updated, we need to reschedule it otherwise old app // list will override everything in processUserApps(). sWorker.post(new Runnable() { public void run() { final List<LauncherActivityInfo> updatedApps = mLauncherApps.getActivityList(null, user); scheduleManagedHeuristicRunnable(heuristic, user, updatedApps); } }); } else { heuristic.processUserApps(apps); } } }; runOnMainThread(new Runnable() { @Override public void run() { // Check isLoadingWorkspace on the UI thread, as it is updated on the UI // thread. if (mIsLoadingAndBindingWorkspace) { synchronized (mBindCompleteRunnables) { mBindCompleteRunnables.add(managedHeuristicRunnable); } } else { runOnWorkerThread(managedHeuristicRunnable); } } }); } }
/** * Checks the list of user apps, and generates package event accordingly. * {@see #onLauncherAppsAdded}, {@see #onLauncherPackageRemoved} */ void processUserApps(List<LauncherActivityInfo> apps, UserHandle user) { String prefKey = INSTALLED_PACKAGES_PREFIX + mUserManager.getSerialNumberForUser(user); HashSet<String> oldPackageSet = new HashSet<>(); final boolean userAppsExisted = getUserApps(oldPackageSet, prefKey); HashSet<String> packagesRemoved = new HashSet<>(oldPackageSet); HashSet<String> newPackageSet = new HashSet<>(); ArrayList<LauncherActivityInstallInfo> packagesAdded = new ArrayList<>(); for (LauncherActivityInfo info : apps) { String packageName = info.getComponentName().getPackageName(); newPackageSet.add(packageName); packagesRemoved.remove(packageName); if (!oldPackageSet.contains(packageName)) { oldPackageSet.add(packageName); packagesAdded.add(new LauncherActivityInstallInfo( info, info.getFirstInstallTime())); } } if (!packagesAdded.isEmpty() || !packagesRemoved.isEmpty()) { mPrefs.edit().putStringSet(prefKey, newPackageSet).apply(); if (!packagesAdded.isEmpty()) { Collections.sort(packagesAdded); onLauncherAppsAdded(packagesAdded, user, userAppsExisted); } if (!packagesRemoved.isEmpty()) { for (String pkg : packagesRemoved) { onLauncherPackageRemoved(pkg, user); } } } }
private Drawable getIconFromHandler(LauncherActivityInfo info) { Bitmap bm = mIconsManager.getDrawableIconForPackage(info.getComponentName()); if (bm == null) { return null; } return new BitmapDrawable(mContext.getResources(), LauncherIcons.createIconBitmap(bm, mContext)); }
public void addCustomInfoToDataBase(Drawable icon, ItemInfo info, CharSequence title) { LauncherActivityInfo app = mLauncherApps.resolveActivity(info.getIntent(), info.user); final ComponentKey key = new ComponentKey(app.getComponentName(), app.getUser()); CacheEntry entry = mCache.get(key); PackageInfo packageInfo = null; try { packageInfo = mPackageManager.getPackageInfo( app.getComponentName().getPackageName(), 0); } catch (NameNotFoundException e) { e.printStackTrace(); } // We can't reuse the entry if the high-res icon is not present. if (entry == null || entry.isLowResIcon || entry.icon == null) { entry = new CacheEntry(); } entry.icon = LauncherIcons.createIconBitmap(icon, mContext); entry.title = title != null ? title : app.getLabel(); entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser()); mCache.put(key, entry); Bitmap lowResIcon = generateLowResIcon(entry.icon, mActivityBgColor); ContentValues values = newContentValues(entry.icon, lowResIcon, entry.title.toString(), app.getApplicationInfo().packageName); if (packageInfo != null) { addIconToDB(values, app.getComponentName(), packageInfo, mUserManager.getSerialNumberForUser(app.getUser())); } }
/** * Updates {@param application} only if a valid entry is found. */ public synchronized void updateTitleAndIcon(AppInfo application) { CacheEntry entry = cacheLocked(application.componentName, Provider.<LauncherActivityInfo>of(null), application.user, false, application.usingLowResIcon); if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) { applyCacheEntry(entry, application); } }
/** * Fill in {@param info} with the icon and label for {@param activityInfo} */ public synchronized void getTitleAndIcon(ItemInfoWithIcon info, LauncherActivityInfo activityInfo, boolean useLowResIcon) { // If we already have activity info, no need to use package icon getTitleAndIcon(info, Provider.of(activityInfo), false, useLowResIcon); }
/** * Fill in {@param shortcutInfo} with the icon and label for {@param info} */ private synchronized void getTitleAndIcon( @NonNull ItemInfoWithIcon infoInOut, @NonNull Provider<LauncherActivityInfo> activityInfoProvider, boolean usePkgIcon, boolean useLowResIcon) { CacheEntry entry = cacheLocked(infoInOut.getTargetComponent(), activityInfoProvider, infoInOut.user, usePkgIcon, useLowResIcon); applyCacheEntry(entry, infoInOut); }
@Thunk SerializedIconUpdateTask(long userSerial, HashMap<String, PackageInfo> pkgInfoMap, Stack<LauncherActivityInfo> appsToAdd, Stack<LauncherActivityInfo> appsToUpdate) { mUserSerial = userSerial; mPkgInfoMap = pkgInfoMap; mAppsToAdd = appsToAdd; mAppsToUpdate = appsToUpdate; }
/** * Initializes a PendingInstallShortcutInfo to represent a launcher target. */ PendingInstallShortcutInfo(LauncherActivityInfo info, Context context) { activityInfo = info; shortcutInfo = null; providerInfo = null; data = null; user = info.getUser(); mContext = context; launchIntent = AppInfo.makeLaunchIntent(info); label = info.getLabel().toString(); }
public AppInfo(LauncherActivityInfo info, UserHandle user, boolean quietModeEnabled) { this.componentName = info.getComponentName(); this.container = ItemInfo.NO_ID; this.user = user; if (PackageManagerHelper.isAppSuspended(info.getApplicationInfo())) { isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; } if (quietModeEnabled) { isDisabled |= ShortcutInfo.FLAG_DISABLED_QUIET_USER; } intent = makeLaunchIntent(info); }
public List<LauncherActivityInfoCompat> getActivityList(String packageName, UserHandleCompat user) { List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName, user.getUser()); if (list.size() == 0) { return Collections.emptyList(); } ArrayList<LauncherActivityInfoCompat> compatList = new ArrayList<LauncherActivityInfoCompat>(list.size()); for (LauncherActivityInfo info : list) { compatList.add(new LauncherActivityInfoCompatVL(info)); } return compatList; }
public LauncherActivityInfoCompat resolveActivity(Intent intent, UserHandleCompat user) { LauncherActivityInfo activity = mLauncherApps.resolveActivity(intent, user.getUser()); if (activity != null) { return new LauncherActivityInfoCompatVL(activity); } else { return null; } }
public Drawable getIcon(Context context, PackageManager pm, LauncherActivityInfo appInfo) { UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); String name = appInfo.getComponentName().flattenToString() + ":" + userManager.getSerialNumberForUser(appInfo.getUser()); BitmapDrawable drawable; synchronized (drawables) { drawable = drawables.get(name); if(drawable == null) { Drawable loadedIcon = loadIcon(context, pm, appInfo); if(loadedIcon instanceof BitmapDrawable) drawable = (BitmapDrawable) loadedIcon; else { int width = Math.max(loadedIcon.getIntrinsicWidth(), 1); int height = Math.max(loadedIcon.getIntrinsicHeight(), 1); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); loadedIcon.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); loadedIcon.draw(canvas); drawable = new BitmapDrawable(context.getResources(), bitmap); } drawables.put(name, drawable); } } return drawable; }
private Drawable getIcon(PackageManager pm, LauncherActivityInfo appInfo) { try { return appInfo.getBadgedIcon(0); } catch (NullPointerException e) { return pm.getDefaultActivityIcon(); } }
@Override protected void onListItemClick(ListView l, View v, int position, long id) { // launch the app LauncherActivityInfo appInfo = mAdapter.getItem(position); ComponentName appComponent = appInfo.getComponentName(); Intent intent = new Intent(Intent.makeMainActivity(appComponent)); startActivity(intent); // appInfo.getApplicationInfo().processName Intent result = new Intent(); result.putExtra("processName", appInfo.getApplicationInfo().processName); setResult(Activity.RESULT_OK, result); finish(); }
public List<LauncherActivityInfoCompat> getActivityList(String packageName, UserHandleCompat user) { List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName, user.getUser()); if (list.size() == 0) { return Collections.EMPTY_LIST; } ArrayList<LauncherActivityInfoCompat> compatList = new ArrayList<LauncherActivityInfoCompat>(list.size()); for (LauncherActivityInfo info : list) { compatList.add(new LauncherActivityInfoCompatVL(info)); } return compatList; }