Loading packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt +5 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ class AppListRepositoryImpl( matchAnyUserForAdmin: Boolean, ): List<ApplicationInfo> = try { coroutineScope { // TODO(b/382016780): to be removed after flag cleanup. val hiddenSystemModulesDeferred = async { packageManager.getHiddenSystemModules() } val hideWhenDisabledPackagesDeferred = async { context.resources.getStringArray(R.array.config_hideWhenDisabled_packageNames) Loading @@ -95,6 +96,7 @@ class AppListRepositoryImpl( val installedApplicationsAsUser = getInstalledApplications(userId, matchAnyUserForAdmin) // TODO(b/382016780): to be removed after flag cleanup. val hiddenSystemModules = hiddenSystemModulesDeferred.await() val hideWhenDisabledPackages = hideWhenDisabledPackagesDeferred.await() installedApplicationsAsUser.filter { app -> Loading Loading @@ -206,6 +208,7 @@ class AppListRepositoryImpl( private fun isSystemApp(app: ApplicationInfo, homeOrLauncherPackages: Set<String>): Boolean = app.isSystemApp && !app.isUpdatedSystemApp && app.packageName !in homeOrLauncherPackages // TODO(b/382016780): to be removed after flag cleanup. private fun PackageManager.getHiddenSystemModules(): Set<String> { val moduleInfos = getInstalledModules(0).filter { it.isHidden } val hiddenApps = moduleInfos.mapNotNull { it.packageName }.toMutableSet() Loading @@ -218,13 +221,14 @@ class AppListRepositoryImpl( companion object { private const val TAG = "AppListRepository" // TODO(b/382016780): to be removed after flag cleanup. private fun ApplicationInfo.isInAppList( showInstantApps: Boolean, hiddenSystemModules: Set<String>, hideWhenDisabledPackages: Array<String>, ) = when { !showInstantApps && isInstantApp -> false packageName in hiddenSystemModules -> false !Flags.removeHiddenModuleUsage() && (packageName in hiddenSystemModules) -> false packageName in hideWhenDisabledPackages -> enabled && !isDisabledUntilUsed enabled -> true else -> enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER Loading packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt +19 −1 Original line number Diff line number Diff line Loading @@ -281,6 +281,23 @@ class AppListRepositoryTest { ) } @EnableFlags(Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE) @Test fun loadApps_shouldIncludeAllSystemModuleApps() = runTest { packageManager.stub { on { getInstalledModules(any()) } doReturn listOf(HIDDEN_MODULE) } mockInstalledApplications( listOf(NORMAL_APP, HIDDEN_APEX_APP, HIDDEN_MODULE_APP), ADMIN_USER_ID ) val appList = repository.loadApps(userId = ADMIN_USER_ID) assertThat(appList).containsExactly(NORMAL_APP, HIDDEN_APEX_APP, HIDDEN_MODULE_APP) } @DisableFlags(Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE) @EnableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX) @Test fun loadApps_hasApkInApexInfo_shouldNotIncludeAllHiddenApps() = runTest { Loading @@ -297,7 +314,7 @@ class AppListRepositoryTest { assertThat(appList).containsExactly(NORMAL_APP) } @DisableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX) @DisableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX, Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE) @Test fun loadApps_noApkInApexInfo_shouldNotIncludeHiddenSystemModule() = runTest { packageManager.stub { Loading Loading @@ -456,6 +473,7 @@ class AppListRepositoryTest { isArchived = true } // TODO(b/382016780): to be removed after flag cleanup. val HIDDEN_APEX_APP = ApplicationInfo().apply { packageName = "hidden.apex.package" } Loading packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java +1 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ public class AppUtils { /** * Returns a boolean indicating whether the given package is a hidden system module * TODO(b/382016780): to be removed after flag cleanup. */ public static boolean isHiddenSystemModule(Context context, String packageName) { return ApplicationsState.getInstance((Application) context.getApplicationContext()) Loading packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +13 −8 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ public class ApplicationsState { int mCurComputingSizeUserId; boolean mSessionsChanged; // Maps all installed modules on the system to whether they're hidden or not. // TODO(b/382016780): to be removed after flag cleanup. final HashMap<String, Boolean> mSystemModules = new HashMap<>(); // Temporary for dispatching session callbacks. Only touched by main thread. Loading Loading @@ -226,6 +227,7 @@ public class ApplicationsState { mRetrieveFlags = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; if (!Flags.removeHiddenModuleUsage()) { final List<ModuleInfo> moduleInfos = mPm.getInstalledModules(0 /* flags */); for (ModuleInfo info : moduleInfos) { mSystemModules.put(info.getPackageName(), info.isHidden()); Loading @@ -235,6 +237,7 @@ public class ApplicationsState { } } } } /** * This is a trick to prevent the foreground thread from being delayed. Loading Loading @@ -336,7 +339,7 @@ public class ApplicationsState { } mHaveDisabledApps = true; } if (isHiddenModule(info.packageName)) { if (!Flags.removeHiddenModuleUsage() && isHiddenModule(info.packageName)) { mApplications.remove(i--); continue; } Loading Loading @@ -453,6 +456,7 @@ public class ApplicationsState { return mHaveInstantApps; } // TODO(b/382016780): to be removed after flag cleanup. boolean isHiddenModule(String packageName) { Boolean isHidden = mSystemModules.get(packageName); if (isHidden == null) { Loading @@ -462,6 +466,7 @@ public class ApplicationsState { return isHidden; } // TODO(b/382016780): to be removed after flag cleanup. boolean isSystemModule(String packageName) { return mSystemModules.containsKey(packageName); } Loading Loading @@ -755,7 +760,7 @@ public class ApplicationsState { Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry); } if (entry == null) { if (isHiddenModule(info.packageName)) { if (!Flags.removeHiddenModuleUsage() && isHiddenModule(info.packageName)) { if (DEBUG) { Log.i(TAG, "No AppEntry for " + info.packageName + " (hidden module)"); } Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settingslib.applications; import static android.content.pm.Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE; import static android.content.pm.Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX; import static android.os.UserHandle.MU_ENABLED; import static android.os.UserHandle.USER_SYSTEM; Loading Loading @@ -59,6 +60,8 @@ import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.text.TextUtils; import android.util.IconDrawableFactory; Loading Loading @@ -204,6 +207,7 @@ public class ApplicationsStateRoboTest { info.setPackageName(packageName); info.setApkInApexPackageNames(Collections.singletonList(apexPackageName)); // will treat any app with package name that contains "hidden" as hidden module // TODO(b/382016780): to be removed after flag cleanup. info.setHidden(!TextUtils.isEmpty(packageName) && packageName.contains("hidden")); return info; } Loading Loading @@ -414,6 +418,7 @@ public class ApplicationsStateRoboTest { } @Test @DisableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void onResume_shouldNotIncludeSystemHiddenModule() { mSession.onResume(); Loading @@ -423,6 +428,18 @@ public class ApplicationsStateRoboTest { assertThat(mApplications.get(1).packageName).isEqualTo("test.package.3"); } @Test @EnableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void onResume_shouldIncludeSystemModule() { mSession.onResume(); final List<ApplicationInfo> mApplications = mApplicationsState.mApplications; assertThat(mApplications).hasSize(3); assertThat(mApplications.get(0).packageName).isEqualTo("test.package.1"); assertThat(mApplications.get(1).packageName).isEqualTo("test.hidden.module.2"); assertThat(mApplications.get(2).packageName).isEqualTo("test.package.3"); } @Test public void removeAndInstall_noWorkprofile_doResumeIfNeededLocked_shouldClearEntries() throws RemoteException { Loading Loading @@ -832,6 +849,7 @@ public class ApplicationsStateRoboTest { mApplicationsState.mEntriesMap.clear(); ApplicationInfo appInfo = createApplicationInfo(PKG_1, /* uid= */ 0); mApplicationsState.mApplications.add(appInfo); // TODO(b/382016780): to be removed after flag cleanup. mApplicationsState.mSystemModules.put(PKG_1, /* value= */ false); assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ 0).info.packageName) Loading @@ -839,6 +857,7 @@ public class ApplicationsStateRoboTest { } @Test @DisableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void isHiddenModule_hasApkInApexInfo_shouldSupportHiddenApexPackage() { mSetFlagsRule.enableFlags(FLAG_PROVIDE_INFO_OF_APK_IN_APEX); ApplicationsState.sInstance = null; Loading @@ -853,6 +872,7 @@ public class ApplicationsStateRoboTest { } @Test @DisableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void isHiddenModule_noApkInApexInfo_onlySupportHiddenModule() { mSetFlagsRule.disableFlags(FLAG_PROVIDE_INFO_OF_APK_IN_APEX); ApplicationsState.sInstance = null; Loading Loading
packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt +5 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ class AppListRepositoryImpl( matchAnyUserForAdmin: Boolean, ): List<ApplicationInfo> = try { coroutineScope { // TODO(b/382016780): to be removed after flag cleanup. val hiddenSystemModulesDeferred = async { packageManager.getHiddenSystemModules() } val hideWhenDisabledPackagesDeferred = async { context.resources.getStringArray(R.array.config_hideWhenDisabled_packageNames) Loading @@ -95,6 +96,7 @@ class AppListRepositoryImpl( val installedApplicationsAsUser = getInstalledApplications(userId, matchAnyUserForAdmin) // TODO(b/382016780): to be removed after flag cleanup. val hiddenSystemModules = hiddenSystemModulesDeferred.await() val hideWhenDisabledPackages = hideWhenDisabledPackagesDeferred.await() installedApplicationsAsUser.filter { app -> Loading Loading @@ -206,6 +208,7 @@ class AppListRepositoryImpl( private fun isSystemApp(app: ApplicationInfo, homeOrLauncherPackages: Set<String>): Boolean = app.isSystemApp && !app.isUpdatedSystemApp && app.packageName !in homeOrLauncherPackages // TODO(b/382016780): to be removed after flag cleanup. private fun PackageManager.getHiddenSystemModules(): Set<String> { val moduleInfos = getInstalledModules(0).filter { it.isHidden } val hiddenApps = moduleInfos.mapNotNull { it.packageName }.toMutableSet() Loading @@ -218,13 +221,14 @@ class AppListRepositoryImpl( companion object { private const val TAG = "AppListRepository" // TODO(b/382016780): to be removed after flag cleanup. private fun ApplicationInfo.isInAppList( showInstantApps: Boolean, hiddenSystemModules: Set<String>, hideWhenDisabledPackages: Array<String>, ) = when { !showInstantApps && isInstantApp -> false packageName in hiddenSystemModules -> false !Flags.removeHiddenModuleUsage() && (packageName in hiddenSystemModules) -> false packageName in hideWhenDisabledPackages -> enabled && !isDisabledUntilUsed enabled -> true else -> enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER Loading
packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt +19 −1 Original line number Diff line number Diff line Loading @@ -281,6 +281,23 @@ class AppListRepositoryTest { ) } @EnableFlags(Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE) @Test fun loadApps_shouldIncludeAllSystemModuleApps() = runTest { packageManager.stub { on { getInstalledModules(any()) } doReturn listOf(HIDDEN_MODULE) } mockInstalledApplications( listOf(NORMAL_APP, HIDDEN_APEX_APP, HIDDEN_MODULE_APP), ADMIN_USER_ID ) val appList = repository.loadApps(userId = ADMIN_USER_ID) assertThat(appList).containsExactly(NORMAL_APP, HIDDEN_APEX_APP, HIDDEN_MODULE_APP) } @DisableFlags(Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE) @EnableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX) @Test fun loadApps_hasApkInApexInfo_shouldNotIncludeAllHiddenApps() = runTest { Loading @@ -297,7 +314,7 @@ class AppListRepositoryTest { assertThat(appList).containsExactly(NORMAL_APP) } @DisableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX) @DisableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX, Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE) @Test fun loadApps_noApkInApexInfo_shouldNotIncludeHiddenSystemModule() = runTest { packageManager.stub { Loading Loading @@ -456,6 +473,7 @@ class AppListRepositoryTest { isArchived = true } // TODO(b/382016780): to be removed after flag cleanup. val HIDDEN_APEX_APP = ApplicationInfo().apply { packageName = "hidden.apex.package" } Loading
packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java +1 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ public class AppUtils { /** * Returns a boolean indicating whether the given package is a hidden system module * TODO(b/382016780): to be removed after flag cleanup. */ public static boolean isHiddenSystemModule(Context context, String packageName) { return ApplicationsState.getInstance((Application) context.getApplicationContext()) Loading
packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +13 −8 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ public class ApplicationsState { int mCurComputingSizeUserId; boolean mSessionsChanged; // Maps all installed modules on the system to whether they're hidden or not. // TODO(b/382016780): to be removed after flag cleanup. final HashMap<String, Boolean> mSystemModules = new HashMap<>(); // Temporary for dispatching session callbacks. Only touched by main thread. Loading Loading @@ -226,6 +227,7 @@ public class ApplicationsState { mRetrieveFlags = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS; if (!Flags.removeHiddenModuleUsage()) { final List<ModuleInfo> moduleInfos = mPm.getInstalledModules(0 /* flags */); for (ModuleInfo info : moduleInfos) { mSystemModules.put(info.getPackageName(), info.isHidden()); Loading @@ -235,6 +237,7 @@ public class ApplicationsState { } } } } /** * This is a trick to prevent the foreground thread from being delayed. Loading Loading @@ -336,7 +339,7 @@ public class ApplicationsState { } mHaveDisabledApps = true; } if (isHiddenModule(info.packageName)) { if (!Flags.removeHiddenModuleUsage() && isHiddenModule(info.packageName)) { mApplications.remove(i--); continue; } Loading Loading @@ -453,6 +456,7 @@ public class ApplicationsState { return mHaveInstantApps; } // TODO(b/382016780): to be removed after flag cleanup. boolean isHiddenModule(String packageName) { Boolean isHidden = mSystemModules.get(packageName); if (isHidden == null) { Loading @@ -462,6 +466,7 @@ public class ApplicationsState { return isHidden; } // TODO(b/382016780): to be removed after flag cleanup. boolean isSystemModule(String packageName) { return mSystemModules.containsKey(packageName); } Loading Loading @@ -755,7 +760,7 @@ public class ApplicationsState { Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry); } if (entry == null) { if (isHiddenModule(info.packageName)) { if (!Flags.removeHiddenModuleUsage() && isHiddenModule(info.packageName)) { if (DEBUG) { Log.i(TAG, "No AppEntry for " + info.packageName + " (hidden module)"); } Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settingslib.applications; import static android.content.pm.Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE; import static android.content.pm.Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX; import static android.os.UserHandle.MU_ENABLED; import static android.os.UserHandle.USER_SYSTEM; Loading Loading @@ -59,6 +60,8 @@ import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.text.TextUtils; import android.util.IconDrawableFactory; Loading Loading @@ -204,6 +207,7 @@ public class ApplicationsStateRoboTest { info.setPackageName(packageName); info.setApkInApexPackageNames(Collections.singletonList(apexPackageName)); // will treat any app with package name that contains "hidden" as hidden module // TODO(b/382016780): to be removed after flag cleanup. info.setHidden(!TextUtils.isEmpty(packageName) && packageName.contains("hidden")); return info; } Loading Loading @@ -414,6 +418,7 @@ public class ApplicationsStateRoboTest { } @Test @DisableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void onResume_shouldNotIncludeSystemHiddenModule() { mSession.onResume(); Loading @@ -423,6 +428,18 @@ public class ApplicationsStateRoboTest { assertThat(mApplications.get(1).packageName).isEqualTo("test.package.3"); } @Test @EnableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void onResume_shouldIncludeSystemModule() { mSession.onResume(); final List<ApplicationInfo> mApplications = mApplicationsState.mApplications; assertThat(mApplications).hasSize(3); assertThat(mApplications.get(0).packageName).isEqualTo("test.package.1"); assertThat(mApplications.get(1).packageName).isEqualTo("test.hidden.module.2"); assertThat(mApplications.get(2).packageName).isEqualTo("test.package.3"); } @Test public void removeAndInstall_noWorkprofile_doResumeIfNeededLocked_shouldClearEntries() throws RemoteException { Loading Loading @@ -832,6 +849,7 @@ public class ApplicationsStateRoboTest { mApplicationsState.mEntriesMap.clear(); ApplicationInfo appInfo = createApplicationInfo(PKG_1, /* uid= */ 0); mApplicationsState.mApplications.add(appInfo); // TODO(b/382016780): to be removed after flag cleanup. mApplicationsState.mSystemModules.put(PKG_1, /* value= */ false); assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ 0).info.packageName) Loading @@ -839,6 +857,7 @@ public class ApplicationsStateRoboTest { } @Test @DisableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void isHiddenModule_hasApkInApexInfo_shouldSupportHiddenApexPackage() { mSetFlagsRule.enableFlags(FLAG_PROVIDE_INFO_OF_APK_IN_APEX); ApplicationsState.sInstance = null; Loading @@ -853,6 +872,7 @@ public class ApplicationsStateRoboTest { } @Test @DisableFlags({FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void isHiddenModule_noApkInApexInfo_onlySupportHiddenModule() { mSetFlagsRule.disableFlags(FLAG_PROVIDE_INFO_OF_APK_IN_APEX); ApplicationsState.sInstance = null; Loading