From ba1b753b85d592daa621bad0a1d7388b996a0453 Mon Sep 17 00:00:00 2001 From: Ricky Wai Date: Thu, 5 Sep 2019 18:21:29 +0100 Subject: [PATCH] Do not return synthetic launcher activity for completely headless apps Bug: 140477182 Test: Headless app: no icon is shown on launcher Test: App with launchable activity but disabled by default: no icon Test: App with launchable activity, enabled by default but then disabled by command: has an icon on launcher Change-Id: I58a36ac93d34583b2d4e50464b73cced77ce8edb Merged-In: I58a36ac93d34583b2d4e50464b73cced77ce8edb (cherry picked from commit 3eb1cc6588b81102732a446a2adcdc799a2cf3d0) --- .../com/android/server/pm/LauncherAppsService.java | 54 ++++++++++------------ 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 9b6333d7bef4..3464cab99d93 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -443,45 +443,39 @@ public class LauncherAppsService extends SystemService { if (isManagedProfileAdmin(user, appInfo.packageName)) { return false; } - // If app does not have any components or any permissions, the app can legitimately - // have no icon so we do not show the synthetic activity. - return hasComponentsAndRequestsPermissions(appInfo.packageName); - } - - private boolean hasComponentsAndRequestsPermissions(@NonNull String packageName) { final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); - final PackageParser.Package pkg = pmInt.getPackage(packageName); + final PackageParser.Package pkg = pmInt.getPackage(appInfo.packageName); if (pkg == null) { // Should not happen, but we shouldn't be failing if it does return false; } - if (ArrayUtils.isEmpty(pkg.requestedPermissions)) { - return false; - } - if (!hasApplicationDeclaredActivities(pkg) - && ArrayUtils.isEmpty(pkg.receivers) - && ArrayUtils.isEmpty(pkg.providers) - && ArrayUtils.isEmpty(pkg.services)) { - return false; - } - return true; + // If app does not have any default enabled launcher activity or any permissions, + // the app can legitimately have no icon so we do not show the synthetic activity. + return requestsPermissions(pkg) && hasDefaultEnableLauncherActivity( + appInfo.packageName); } - private boolean hasApplicationDeclaredActivities(@NonNull PackageParser.Package pkg) { - if (pkg.activities == null) { - return false; - } - if (ArrayUtils.isEmpty(pkg.activities)) { - return false; - } - // If it only contains synthetic AppDetailsActivity only, it means application does - // not have actual activity declared in manifest. - if (pkg.activities.size() == 1 && PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals( - pkg.activities.get(0).className)) { - return false; + private boolean requestsPermissions(@NonNull PackageParser.Package pkg) { + return !ArrayUtils.isEmpty(pkg.requestedPermissions); + } + + private boolean hasDefaultEnableLauncherActivity(@NonNull String packageName) { + final PackageManagerInternal pmInt = + LocalServices.getService(PackageManagerInternal.class); + final Intent matchIntent = new Intent(Intent.ACTION_MAIN); + matchIntent.addCategory(Intent.CATEGORY_LAUNCHER); + matchIntent.setPackage(packageName); + final List infoList = pmInt.queryIntentActivities(matchIntent, + PackageManager.MATCH_DISABLED_COMPONENTS, Binder.getCallingUid(), + getCallingUserId()); + final int size = infoList.size(); + for (int i = 0; i < size; i++) { + if (infoList.get(i).activityInfo.enabled) { + return true; + } } - return true; + return false; } private boolean isManagedProfileAdmin(UserHandle user, String packageName) { -- 2.11.0