diff options
4 files changed, 95 insertions, 112 deletions
diff --git a/core/java/android/content/pm/AppsQueryHelper.java b/core/java/android/content/pm/AppsQueryHelper.java index a5a8e3f9c211..084bc18ea6fe 100644 --- a/core/java/android/content/pm/AppsQueryHelper.java +++ b/core/java/android/content/pm/AppsQueryHelper.java @@ -18,13 +18,11 @@ package android.content.pm; import android.Manifest; import android.app.AppGlobals; -import android.content.Context; import android.content.Intent; import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; -import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethod; import com.android.internal.annotations.VisibleForTesting; @@ -44,36 +42,37 @@ public class AppsQueryHelper { public static int GET_NON_LAUNCHABLE_APPS = 1; /** - * Return apps with {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission + * Return apps with {@link Manifest.permission#INTERACT_ACROSS_USERS} permission */ public static int GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM = 1 << 1; /** - * Return all input methods that are marked as default. - * <p>When this flag is set, {@code user} specified in - * {@link #queryApps(int, boolean, UserHandle)} must be - * {@link UserHandle#myUserId user of the current process}. + * Return all input methods available for the current user. */ - public static int GET_DEFAULT_IMES = 1 << 2; + public static int GET_IMES = 1 << 2; - private final Context mContext; + private final IPackageManager mPackageManager; private List<ApplicationInfo> mAllApps; - public AppsQueryHelper(Context context) { - mContext = context; + public AppsQueryHelper(IPackageManager packageManager) { + mPackageManager = packageManager; + } + + public AppsQueryHelper() { + this(AppGlobals.getPackageManager()); } /** * Return a List of all packages that satisfy a specified criteria. * @param flags search flags. Use any combination of {@link #GET_NON_LAUNCHABLE_APPS}, - * {@link #GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM} or {@link #GET_DEFAULT_IMES}. + * {@link #GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM} or {@link #GET_IMES}. * @param systemAppsOnly if true, only system apps will be returned * @param user user, whose apps are queried */ public List<String> queryApps(int flags, boolean systemAppsOnly, UserHandle user) { boolean nonLaunchableApps = (flags & GET_NON_LAUNCHABLE_APPS) > 0; boolean interactAcrossUsers = (flags & GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM) > 0; - boolean defaultImes = (flags & GET_DEFAULT_IMES) > 0; + boolean imes = (flags & GET_IMES) > 0; if (mAllApps == null) { mAllApps = getAllApps(user.getIdentifier()); } @@ -113,7 +112,6 @@ public class AppsQueryHelper { } } } - if (interactAcrossUsers) { final List<PackageInfo> packagesHoldingPermissions = getPackagesHoldingPermission( Manifest.permission.INTERACT_ACROSS_USERS, user.getIdentifier()); @@ -129,29 +127,18 @@ public class AppsQueryHelper { } } - if (defaultImes) { - if (UserHandle.myUserId() != user.getIdentifier()) { - throw new IllegalArgumentException("Specified user handle " + user - + " is not a user of the current process."); - } - List<InputMethodInfo> imis = getInputMethodList(); - int imisSize = imis.size(); - ArraySet<String> defaultImePackages = new ArraySet<>(); - for (int i = 0; i < imisSize; i++) { - InputMethodInfo imi = imis.get(i); - if (imi.isDefault(mContext)) { - defaultImePackages.add(imi.getPackageName()); - } - } - final int allAppsSize = mAllApps.size(); - for (int i = 0; i < allAppsSize; i++) { - final ApplicationInfo appInfo = mAllApps.get(i); - if (systemAppsOnly && !appInfo.isSystemApp()) { + if (imes) { + final List<ResolveInfo> resolveInfos = queryIntentServicesAsUser( + new Intent(InputMethod.SERVICE_INTERFACE), user.getIdentifier()); + final int resolveInfosSize = resolveInfos.size(); + + for (int i = 0; i < resolveInfosSize; i++) { + ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo; + if (systemAppsOnly && !serviceInfo.applicationInfo.isSystemApp()) { continue; } - final String packageName = appInfo.packageName; - if (defaultImePackages.contains(packageName)) { - result.add(packageName); + if (!result.contains(serviceInfo.packageName)) { + result.add(serviceInfo.packageName); } } } @@ -163,9 +150,8 @@ public class AppsQueryHelper { @SuppressWarnings("unchecked") protected List<ApplicationInfo> getAllApps(int userId) { try { - return AppGlobals.getPackageManager().getInstalledApplications( - PackageManager.GET_UNINSTALLED_PACKAGES - | PackageManager.GET_DISABLED_COMPONENTS, userId).getList(); + return mPackageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES + | PackageManager.GET_DISABLED_COMPONENTS, userId).getList(); } catch (RemoteException e) { throw new IllegalStateException("Package manager has died", e); } @@ -173,17 +159,22 @@ public class AppsQueryHelper { @VisibleForTesting protected List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int userId) { - return mContext.getPackageManager() - .queryIntentActivitiesAsUser(intent, PackageManager.GET_DISABLED_COMPONENTS - | PackageManager.GET_UNINSTALLED_PACKAGES, userId); + try { + return mPackageManager.queryIntentActivities(intent, null, + PackageManager.GET_DISABLED_COMPONENTS + | PackageManager.GET_UNINSTALLED_PACKAGES, + userId); + } catch (RemoteException e) { + throw new IllegalStateException("Package manager has died", e); + } } @VisibleForTesting - @SuppressWarnings("unchecked") - protected List<PackageInfo> getPackagesHoldingPermission(String perm, int userId) { + protected List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int userId) { try { - return AppGlobals.getPackageManager().getPackagesHoldingPermissions(new String[]{perm}, - 0, userId).getList(); + return mPackageManager.queryIntentServices(intent, null, + PackageManager.GET_META_DATA + | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, userId); } catch (RemoteException e) { throw new IllegalStateException("Package manager has died", e); } @@ -191,9 +182,13 @@ public class AppsQueryHelper { @VisibleForTesting @SuppressWarnings("unchecked") - protected List<InputMethodInfo> getInputMethodList() { - InputMethodManager imm = (InputMethodManager) - mContext.getSystemService(Context.INPUT_METHOD_SERVICE); - return imm.getInputMethodList(); + protected List<PackageInfo> getPackagesHoldingPermission(String perm, int userId) { + try { + return mPackageManager.getPackagesHoldingPermissions(new String[]{perm}, 0, + userId).getList(); + } catch (RemoteException e) { + throw new IllegalStateException("Package manager has died", e); + } } + } diff --git a/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java b/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java index 4c9b00aa9a6e..dcf2c890a3cf 100644 --- a/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java +++ b/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java @@ -33,7 +33,7 @@ public class AppsQueryHelperTests extends AndroidTestCase { @Override public void setUp() throws Exception { super.setUp(); - mAppsQueryHelper = new AppsQueryHelperTestable(getContext()); + mAppsQueryHelper = new AppsQueryHelperTestable(); } public void testQueryAppsSystemAppsOnly() { @@ -78,33 +78,20 @@ public class AppsQueryHelperTests extends AndroidTestCase { assertEqualsIgnoreOrder(Arrays.asList("sys_app1", "sys_app3"), apps); } - public void testQueryAppsDefaultIme() { - // Test query default system IMEs - List<String> apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_IMES, + public void testQueryAppsImes() { + // Test query system IMEs + List<String> apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_IMES, true, UserHandle.of(UserHandle.myUserId())); assertEqualsIgnoreOrder(Arrays.asList("sys_app1"), apps); - // Test query default IMEs - apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_IMES, false, + // Test query IMEs + apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_IMES, false, UserHandle.of(UserHandle.myUserId())); assertEqualsIgnoreOrder(Arrays.asList("sys_app1", "app4"), apps); - - // Test that GET_DEFAULT_IMES cannot be used with a user id different from current process - try { - mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_IMES, false, - UserHandle.of(UserHandle.USER_NULL)); - fail("queryApps must fail if wrong user was passed"); - } catch (IllegalArgumentException e) { - // OK - } } private class AppsQueryHelperTestable extends AppsQueryHelper { - public AppsQueryHelperTestable(Context context) { - super(context); - } - @Override protected List<ApplicationInfo> getAllApps(int userId) { final ApplicationInfo ai1 = new ApplicationInfo(); @@ -145,18 +132,19 @@ public class AppsQueryHelperTests extends AndroidTestCase { } @Override - protected List<InputMethodInfo> getInputMethodList() { + protected List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int userId) { final ResolveInfo sysApp1 = new ResolveInfo(); sysApp1.serviceInfo = new ServiceInfo(); sysApp1.serviceInfo.packageName = "sys_app1"; sysApp1.serviceInfo.name = "name"; - InputMethodInfo imi1 = new InputMethodInfo(sysApp1, false, null, null, 0, true); + sysApp1.serviceInfo.applicationInfo = new ApplicationInfo(); + sysApp1.serviceInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; final ResolveInfo app4 = new ResolveInfo(); app4.serviceInfo = new ServiceInfo(); app4.serviceInfo.packageName = "app4"; app4.serviceInfo.name = "name"; - InputMethodInfo imi2 = new InputMethodInfo(app4, false, null, null, 0, true); - return Arrays.asList(imi1, imi2); + app4.serviceInfo.applicationInfo = new ApplicationInfo(); + return Arrays.asList(sysApp1, app4); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index cde126ad23fb..566065c02852 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -12102,8 +12102,6 @@ public final class ActivityManagerService extends ActivityManagerNative } } - enableSystemUserApps(); - // Start up initial activity. mBooting = true; startHomeActivityLocked(currentUserId, "systemReady"); @@ -12155,43 +12153,6 @@ public final class ActivityManagerService extends ActivityManagerNative } } - private void enableSystemUserApps() { - // For system user, enable apps based on the following conditions: - // - app is whitelisted; or has no launcher icons; or has INTERACT_ACROSS_USERS permission - // - app is not in the blacklist - if (UserManager.isSplitSystemUser()) { - AppsQueryHelper queryHelper = new AppsQueryHelper(mContext); - Set<String> enableApps = new HashSet<>(); - enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS - | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM - | AppsQueryHelper.GET_DEFAULT_IMES, - /* systemAppsOnly */ true, UserHandle.SYSTEM)); - ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); - enableApps.addAll(wlApps); - ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); - enableApps.removeAll(blApps); - - List<String> systemApps = queryHelper.queryApps(0, /* systemAppsOnly */ true, - UserHandle.SYSTEM); - final int systemAppsSize = systemApps.size(); - for (int i = 0; i < systemAppsSize; i++) { - String pName = systemApps.get(i); - boolean enable = enableApps.contains(pName); - try { - if (enable) { - AppGlobals.getPackageManager().installExistingPackageAsUser(pName, - UserHandle.USER_SYSTEM); - } else { - AppGlobals.getPackageManager().deletePackageAsUser(pName, null, - UserHandle.USER_SYSTEM, PackageManager.DELETE_SYSTEM_APP); - } - } catch (RemoteException e) { - Slog.e(TAG, "Error occured when processing package " + pName, e); - } - } - } - } - private boolean makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace) { app.crashing = true; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 64628aafbaa2..cdcf79d8d8a6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -105,6 +105,7 @@ import android.content.IntentSender.SendIntentException; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.AppsQueryHelper; import android.content.pm.FeatureInfo; import android.content.pm.IOnPermissionsChangeListener; import android.content.pm.IPackageDataObserver; @@ -1810,10 +1811,48 @@ public class PackageManagerService extends IPackageManager.Stub { boolean factoryTest, boolean onlyCore) { PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore); + m.enableSystemUserApps(); ServiceManager.addService("package", m); return m; } + private void enableSystemUserApps() { + if (!UserManager.isSplitSystemUser()) { + return; + } + // For system user, enable apps based on the following conditions: + // - app is whitelisted or belong to one of these groups: + // -- system app which has no launcher icons + // -- system app which has INTERACT_ACROSS_USERS permission + // -- system IME app + // - app is not in the blacklist + AppsQueryHelper queryHelper = new AppsQueryHelper(this); + Set<String> enableApps = new ArraySet<>(); + enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS + | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM + | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); + ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); + enableApps.addAll(wlApps); + ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); + enableApps.removeAll(blApps); + + List<String> systemApps = queryHelper.queryApps(0, /* systemAppsOnly */ true, + UserHandle.SYSTEM); + final int systemAppsSize = systemApps.size(); + synchronized (mPackages) { + for (int i = 0; i < systemAppsSize; i++) { + String pName = systemApps.get(i); + PackageSetting pkgSetting = mSettings.mPackages.get(pName); + // Should not happen, but we shouldn't be failing if it does + if (pkgSetting == null) { + continue; + } + boolean installed = enableApps.contains(pName); + pkgSetting.setInstalled(installed, UserHandle.USER_SYSTEM); + } + } + } + static String[] splitString(String str, char sep) { int count = 1; int i = 0; |