Loading core/java/android/content/pm/AppsQueryHelper.java +47 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ 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 com.android.internal.annotations.VisibleForTesting; Loading @@ -46,6 +48,14 @@ public class AppsQueryHelper { */ 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}. */ public static int GET_DEFAULT_IMES = 1 << 2; private final Context mContext; private List<ApplicationInfo> mAllApps; Loading @@ -56,13 +66,14 @@ public class AppsQueryHelper { /** * 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} * {@link #GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM} or {@link #GET_DEFAULT_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; if (mAllApps == null) { mAllApps = getAllApps(user.getIdentifier()); } Loading Loading @@ -118,6 +129,33 @@ 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()) { continue; } final String packageName = appInfo.packageName; if (defaultImePackages.contains(packageName)) { result.add(packageName); } } } return result; } Loading Loading @@ -150,4 +188,12 @@ public class AppsQueryHelper { throw new IllegalStateException("Package manager has died", e); } } @VisibleForTesting @SuppressWarnings("unchecked") protected List<InputMethodInfo> getInputMethodList() { InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); return imm.getInputMethodList(); } } core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java +37 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.os.UserHandle; import android.test.AndroidTestCase; import android.view.inputmethod.InputMethodInfo; import java.util.Arrays; import java.util.HashSet; Loading Loading @@ -77,6 +78,27 @@ 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, true, UserHandle.of(UserHandle.myUserId())); assertEqualsIgnoreOrder(Arrays.asList("sys_app1"), apps); // Test query default IMEs apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_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) { Loading Loading @@ -121,6 +143,21 @@ public class AppsQueryHelperTests extends AndroidTestCase { p1.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; return Arrays.asList(p1); } @Override protected List<InputMethodInfo> getInputMethodList() { 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); 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); } } private static void assertEqualsIgnoreOrder(List<String> expected, List<String> actual) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +2 −1 Original line number Diff line number Diff line Loading @@ -12106,7 +12106,8 @@ public final class ActivityManagerService extends ActivityManagerNative 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_APPS_WITH_INTERACT_ACROSS_USERS_PERM | AppsQueryHelper.GET_DEFAULT_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); enableApps.addAll(wlApps); Loading Loading
core/java/android/content/pm/AppsQueryHelper.java +47 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ 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 com.android.internal.annotations.VisibleForTesting; Loading @@ -46,6 +48,14 @@ public class AppsQueryHelper { */ 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}. */ public static int GET_DEFAULT_IMES = 1 << 2; private final Context mContext; private List<ApplicationInfo> mAllApps; Loading @@ -56,13 +66,14 @@ public class AppsQueryHelper { /** * 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} * {@link #GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM} or {@link #GET_DEFAULT_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; if (mAllApps == null) { mAllApps = getAllApps(user.getIdentifier()); } Loading Loading @@ -118,6 +129,33 @@ 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()) { continue; } final String packageName = appInfo.packageName; if (defaultImePackages.contains(packageName)) { result.add(packageName); } } } return result; } Loading Loading @@ -150,4 +188,12 @@ public class AppsQueryHelper { throw new IllegalStateException("Package manager has died", e); } } @VisibleForTesting @SuppressWarnings("unchecked") protected List<InputMethodInfo> getInputMethodList() { InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); return imm.getInputMethodList(); } }
core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java +37 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.os.UserHandle; import android.test.AndroidTestCase; import android.view.inputmethod.InputMethodInfo; import java.util.Arrays; import java.util.HashSet; Loading Loading @@ -77,6 +78,27 @@ 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, true, UserHandle.of(UserHandle.myUserId())); assertEqualsIgnoreOrder(Arrays.asList("sys_app1"), apps); // Test query default IMEs apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_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) { Loading Loading @@ -121,6 +143,21 @@ public class AppsQueryHelperTests extends AndroidTestCase { p1.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; return Arrays.asList(p1); } @Override protected List<InputMethodInfo> getInputMethodList() { 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); 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); } } private static void assertEqualsIgnoreOrder(List<String> expected, List<String> actual) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +2 −1 Original line number Diff line number Diff line Loading @@ -12106,7 +12106,8 @@ public final class ActivityManagerService extends ActivityManagerNative 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_APPS_WITH_INTERACT_ACROSS_USERS_PERM | AppsQueryHelper.GET_DEFAULT_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); enableApps.addAll(wlApps); Loading