From f480cdd56fa15eb7e2038d1d74a735e245428019 Mon Sep 17 00:00:00 2001 From: Alyssa Ketpreechasawat Date: Fri, 4 Oct 2024 16:22:43 +0000 Subject: [PATCH] Remove ModuleInfo#isHidden Usage from the source code. ModuleInfo#isHidden is used for getting hidden module status from ModuleMetadata package (Mainline). It was set to hide Mainline modules' Apk to show in the Settings UI and this has caused the issue as it disallowed the user to toggle permissions where it was needed. Thus, we decided to deprecate the usage of ModuleInfo#isHidden (see go/aml-hidden-modules-permissions). Bug: 379056868 Test: unittest Test: check behavior before/after enable flags Flag: android.content.pm.remove_hidden_module_usage Change-Id: I670c95350e3c21db9f74f37b675aba1b23c67a61 --- .../applications/RecentAppStatsMixin.java | 3 +- .../appinfo/AppInfoDashboardFragment.java | 3 +- .../settings/fuelgauge/BatteryUtils.java | 8 ++- .../applications/RecentAppStatsMixinTest.java | 60 +++++++++++++++++++ .../AppButtonsPreferenceControllerTest.java | 19 ++++++ .../appinfo/AppInfoDashboardFragmentTest.java | 2 + 6 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/applications/RecentAppStatsMixin.java b/src/com/android/settings/applications/RecentAppStatsMixin.java index 4e8f795d8c2..2a79a61a94f 100644 --- a/src/com/android/settings/applications/RecentAppStatsMixin.java +++ b/src/com/android/settings/applications/RecentAppStatsMixin.java @@ -186,7 +186,8 @@ public class RecentAppStatsMixin implements LifecycleObserver, OnStart { return false; } - if (AppUtils.isHiddenSystemModule(mContext, pkgName)) { + if (!android.content.pm.Flags.removeHiddenModuleUsage() + && AppUtils.isHiddenSystemModule(mContext, pkgName)) { return false; } diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 1712e85259c..b0f291c833d 100644 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -243,7 +243,7 @@ public class AppInfoDashboardFragment extends DashboardFragment if (!ensurePackageInfoAvailable(activity)) { return; } - if (!ensureDisplayableModule(activity)) { + if (!android.content.pm.Flags.removeHiddenModuleUsage() && !ensureDisplayableModule(activity)) { return; } startListeningToPackageRemove(); @@ -386,6 +386,7 @@ public class AppInfoDashboardFragment extends DashboardFragment * If it's not, the fragment will finish. * * @return true if package is displayable. + * TODO(b/382016780): to be removed after flag cleanup. */ @VisibleForTesting boolean ensureDisplayableModule(Activity activity) { diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index 7cb5733a9b0..3ef5650cdb7 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -223,10 +223,16 @@ public class BatteryUtils { public boolean shouldHideUidBatteryConsumerUnconditionally( UidBatteryConsumer consumer, String[] packages) { final int uid = consumer.getUid(); + if (android.content.pm.Flags.removeHiddenModuleUsage()) { + return uid == UID_TETHERING ? false : uid < 0; + } return uid == UID_TETHERING ? false : uid < 0 || isHiddenSystemModule(packages); } - /** Returns true if one the specified packages belongs to a hidden system module. */ + /** + * Returns true if one the specified packages belongs to a hidden system module. + * TODO(b/382016780): to be removed after flag cleanup. + */ public boolean isHiddenSystemModule(String[] packages) { if (packages != null) { for (int i = 0, length = packages.length; i < length; i++) { diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppStatsMixinTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppStatsMixinTest.java index 4fb0c0501fd..b62430d1837 100644 --- a/tests/robotests/src/com/android/settings/applications/RecentAppStatsMixinTest.java +++ b/tests/robotests/src/com/android/settings/applications/RecentAppStatsMixinTest.java @@ -38,12 +38,16 @@ import android.content.pm.ResolveInfo; import android.os.PowerManager; 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 com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.instantapps.InstantAppDataProvider; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -88,6 +92,9 @@ public class RecentAppStatsMixinTest { private RecentAppStatsMixin mRecentAppStatsMixin; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Before public void setUp() throws PackageManager.NameNotFoundException { MockitoAnnotations.initMocks(this); @@ -255,6 +262,59 @@ public class RecentAppStatsMixinTest { } @Test + @EnableFlags({android.content.pm.Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE}) + public void loadDisplayableRecentApps_twoSystemModulesSet_shouldHaveTwoSystemModules() { + final List stats = new ArrayList<>(); + + // System modules. + final UsageStats stat1 = new UsageStats(); + stat1.mLastTimeUsed = System.currentTimeMillis(); + stat1.mPackageName = "com.foo.module1"; + stats.add(stat1); + + final UsageStats stat2 = new UsageStats(); + stat2.mLastTimeUsed = System.currentTimeMillis() + 200; + stat2.mPackageName = "com.foo.module2"; + stats.add(stat2); + + ApplicationsState.AppEntry stat1Entry = mock(ApplicationsState.AppEntry.class); + ApplicationsState.AppEntry stat2Entry = mock(ApplicationsState.AppEntry.class); + stat1Entry.info = mApplicationInfo; + stat2Entry.info = mApplicationInfo; + + when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId())).thenReturn(stat1Entry); + when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId())).thenReturn(stat2Entry); + + // Hidden status set to false and true, but they should not cause the difference in + // the behavior. + final ModuleInfo moduleInfo1 = new ModuleInfo(); + moduleInfo1.setPackageName(stat1.mPackageName); + moduleInfo1.setHidden(false); + + final ModuleInfo moduleInfo2 = new ModuleInfo(); + moduleInfo2.setPackageName(stat2.mPackageName); + moduleInfo2.setHidden(true); + + ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", null); + final List modules = new ArrayList<>(); + modules.add(moduleInfo1); + modules.add(moduleInfo2); + when(mPackageManager.getInstalledModules(anyInt() /* flags */)) + .thenReturn(modules); + + when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt())) + .thenReturn(new ResolveInfo()); + when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) + .thenReturn(stats); + + mRecentAppStatsMixin.loadDisplayableRecentApps(3); + + assertThat(mRecentAppStatsMixin.mRecentApps.size()).isEqualTo(2); + } + + // TODO(b/382016780): to be removed after flag cleanup. + @Test + @DisableFlags({android.content.pm.Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void loadDisplayableRecentApps_hiddenSystemModuleSet_shouldNotHaveHiddenSystemModule() { final List stats = new ArrayList<>(); // Regular app. diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java index 6fc01fc52ed..a731d76e1f4 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java @@ -50,7 +50,9 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.RemoteException; import android.os.UserManager; +import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArraySet; import android.view.View; @@ -68,6 +70,7 @@ import com.android.settingslib.widget.ActionButtonsPreference; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; @@ -128,6 +131,9 @@ public class AppButtonsPreferenceControllerTest { private ActionButtonsPreference mButtonPrefs; private AppButtonsPreferenceController mController; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -543,12 +549,21 @@ public class AppButtonsPreferenceControllerTest { @Test @Config(shadows = ShadowAppUtils.class) + @DisableFlags({android.content.pm.Flags.FLAG_REMOVE_HIDDEN_MODULE_USAGE}) public void getAvailabilityStatus_systemModule() { ShadowAppUtils.addHiddenModule(mController.mPackageName); assertThat(mController.getAvailabilityStatus()).isEqualTo( AppButtonsPreferenceController.DISABLED_FOR_USER); } + @Test + @Config(shadows = ShadowAppUtils.class) + public void getAvailabilityStatus_mainlineModule() { + ShadowAppUtils.addMainlineModule(mController.mPackageName); + assertThat(mController.getAvailabilityStatus()).isEqualTo( + AppButtonsPreferenceController.DISABLED_FOR_USER); + } + @Test public void handleActivityResult_onAppUninstall_removeTask() { mController.handleActivityResult(REQUEST_UNINSTALL, 0, new Intent()); @@ -639,15 +654,18 @@ public class AppButtonsPreferenceControllerTest { @Implements(AppUtils.class) public static class ShadowAppUtils { + // TODO(b/382016780): to be removed after flag cleanup. public static Set sSystemModules = new ArraySet<>(); public static Set sMainlineModules = new ArraySet<>(); @Resetter public static void reset() { + // TODO(b/382016780): to be removed after flag cleanup. sSystemModules.clear(); sMainlineModules.clear(); } + // TODO(b/382016780): to be removed after flag cleanup. public static void addHiddenModule(String pkg) { sSystemModules.add(pkg); } @@ -661,6 +679,7 @@ public class AppButtonsPreferenceControllerTest { return false; } + // TODO(b/382016780): to be removed after flag cleanup. @Implementation protected static boolean isSystemModule(Context context, String packageName) { return sSystemModules.contains(packageName); diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java index 46d1cc3a534..2699058b18d 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java @@ -205,6 +205,7 @@ public final class AppInfoDashboardFragmentTest { verify(mActivity, never()).finishAndRemoveTask(); } + // TODO(b/382016780): to be removed after flag cleanup. @Test @Config(shadows = ShadowAppUtils.class) public void ensureDisplayableModule_hiddenModule_shouldReturnFalse() { @@ -215,6 +216,7 @@ public final class AppInfoDashboardFragmentTest { assertThat(mFragment.ensureDisplayableModule(mActivity)).isFalse(); } + // TODO(b/382016780): to be removed after flag cleanup. @Test @Config(shadows = ShadowAppUtils.class) public void ensureDisplayableModule_regularApp_shouldReturnTrue() {