From 40ede29ed6467d4d85a482e6008b92aa02d50267 Mon Sep 17 00:00:00 2001 From: sanryhuang Date: Mon, 19 Mar 2018 11:14:04 +0800 Subject: [PATCH] Hide system apps until installed (1/2) Applying this mechanism for system carrier apps to make visibility reasonable from the user's perspective. In other words, before hidden system apps have been installed, they wouldn't be listed via APIs in PackageManager which are used at all apps list and search in Settings and so on. Test: manual Test: atest CarrierAppUtilsTest Test: atest PackageManagerTest Bug: 74068582 Change-Id: Id3ff138ad529b909d9bbf6719af3a553b909ccbb --- .../android/content/pm/IPackageManager.aidl | 2 + .../android/content/pm/PackageManager.java | 11 ++++- .../android/content/pm/PackageParser.java | 10 +++- core/res/AndroidManifest.xml | 9 ++++ .../server/pm/PackageManagerService.java | 49 +++++++++++++++++-- .../internal/telephony/CarrierAppUtils.java | 37 ++++++++------ 6 files changed, 98 insertions(+), 20 deletions(-) diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index c988fa907f867..03e600ed3ba18 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -598,6 +598,8 @@ interface IPackageManager { boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId); boolean getApplicationHiddenSettingAsUser(String packageName, int userId); + boolean setSystemAppInstallState(String packageName, boolean installed, int userId); + IPackageInstaller getPackageInstaller(); boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index c3548e5b2bbae..15aedd7cf5023 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -147,6 +147,7 @@ public abstract class PackageManager { GET_DISABLED_COMPONENTS, GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, + MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, }) @Retention(RetentionPolicy.SOURCE) public @interface PackageInfoFlags {} @@ -164,6 +165,7 @@ public abstract class PackageManager { MATCH_STATIC_SHARED_LIBRARIES, GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, + MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoFlags {} @@ -520,6 +522,12 @@ public abstract class PackageManager { */ public static final int MATCH_DEBUG_TRIAGED_MISSING = 0x10000000; + /** + * Internal flag used to indicate that a package is a hidden system app. + * @hide + */ + public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 0x20000000; + /** * Flag for {@link #addCrossProfileIntentFilter}: if this flag is set: when * resolving an intent that matches the {@code CrossProfileIntentFilter}, @@ -4839,7 +4847,8 @@ public abstract class PackageManager { * on the system for other users, also install it for the specified user. * @hide */ - @RequiresPermission(anyOf = { + @RequiresPermission(anyOf = { + Manifest.permission.INSTALL_EXISTING_PACKAGES, Manifest.permission.INSTALL_PACKAGES, Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract int installExistingPackageAsUser(String packageName, @UserIdInt int userId) diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 2da2cb4c92853..b8eb074d16360 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -639,11 +639,19 @@ public class PackageParser { */ private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state, ApplicationInfo appInfo) { + // Returns false if the package is hidden system app until installed. + if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 + && !state.installed + && appInfo != null && appInfo.isSystemApp()) { + return false; + } + // If available for the target user, or trying to match uninstalled packages and it's // a system app. return state.isAvailable(flags) || (appInfo != null && appInfo.isSystemApp() - && (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0); + && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0 + || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0)); } public static boolean isAvailable(PackageUserState state) { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index e35b63113f596..19e5e21d50935 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3024,6 +3024,15 @@ + + +