From 538accf058366cabc002da8216c46d52633570c5 Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Wed, 9 Jan 2019 14:54:19 -0800 Subject: [PATCH] Hide mainline module apps in settings. - check whether an app is system hidden module and do not show them in recent apps list and battery usage list. Bug: 120546598 Test: make RunSettingsRoboTests Change-Id: I9080c9d39095890f3a3ebc7fce839dcf984a92d6 --- .../RecentAppsPreferenceController.java | 3 + .../BatteryAppListPreferenceController.java | 7 +++ .../RecentAppsPreferenceControllerTest.java | 55 +++++++++++++++++++ ...cialAppAccessPreferenceControllerTest.java | 12 +++- ...atteryAppListPreferenceControllerTest.java | 33 +++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java index b6e8f4c6071..5d5229080c7 100644 --- a/src/com/android/settings/applications/RecentAppsPreferenceController.java +++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java @@ -316,6 +316,9 @@ public class RecentAppsPreferenceController extends AbstractPreferenceController Log.d(TAG, "System package, skipping " + pkgName); return false; } + if (AppUtils.isHiddenSystemModule(mContext, pkgName)) { + return false; + } final Intent launchIntent = new Intent().addCategory(Intent.CATEGORY_LAUNCHER) .setPackage(pkgName); diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java index 65181c4a6c0..e2d1c53eb3e 100644 --- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java +++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java @@ -46,6 +46,7 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.applications.AppUtils; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; @@ -351,6 +352,12 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro @VisibleForTesting boolean shouldHideSipper(BatterySipper sipper) { + // Don't show hidden system module + final String packageName = mBatteryUtils.getPackageName(sipper.getUid()); + if (!TextUtils.isEmpty(packageName) + && AppUtils.isHiddenSystemModule(mContext, packageName)) { + return true; + } // Don't show over-counted and unaccounted in any condition return sipper.drainType == BatterySipper.DrainType.OVERCOUNTED || sipper.drainType == BatterySipper.DrainType.UNACCOUNTED; diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java index aab2156de08..3fd43695396 100644 --- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java @@ -38,6 +38,7 @@ import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.pm.ModuleInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.PowerManager; @@ -102,10 +103,13 @@ public class RecentAppsPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + when(mContext.getApplicationContext()).thenReturn(mContext); + ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", mAppState); doReturn(mUsageStatsManager).when(mContext).getSystemService(Context.USAGE_STATS_SERVICE); doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE); doReturn(mPackageManager).when(mContext).getPackageManager(); doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); + when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {}); mController = new RecentAppsPreferenceController(mContext, mAppState, null); when(mScreen.findPreference(anyString())).thenReturn(mCategory); @@ -350,6 +354,57 @@ public class RecentAppsPreferenceControllerTest { verify(mCategory).addPreference(argThat(summaryMatches("0 minutes ago"))); } + @Test + public void displayPreference_shouldNotShowHiddenSystemModule() { + final List stats = new ArrayList<>(); + // Regular app. + final UsageStats stat1 = new UsageStats(); + stat1.mLastTimeUsed = System.currentTimeMillis(); + stat1.mPackageName = "com.foo.bar"; + stats.add(stat1); + + // Hidden system module. + final UsageStats stat2 = new UsageStats(); + stat2.mLastTimeUsed = System.currentTimeMillis() + 200; + stat2.mPackageName = "com.foo.hidden"; + 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); + + 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(moduleInfo2); + when(mPackageManager.getInstalledModules(anyInt() /* flags */)) + .thenReturn(modules); + + when(mPackageManager.resolveActivity(any(Intent.class), anyInt())) + .thenReturn(new ResolveInfo()); + when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) + .thenReturn(stats); + + mController.displayPreference(mScreen); + + // Only add stat1. stat2 is skipped because it is hidden module. + final ArgumentCaptor prefCaptor = ArgumentCaptor.forClass(Preference.class); + verify(mCategory).addPreference(prefCaptor.capture()); + final Preference pref = prefCaptor.getValue(); + assertThat(pref.getKey()).isEqualTo(stat1.mPackageName); + } + private static ArgumentMatcher summaryMatches(String expected) { return preference -> TextUtils.equals(expected, preference.getSummary()); } diff --git a/tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java index e2035e33c42..75302d837c3 100644 --- a/tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java @@ -20,11 +20,16 @@ import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEA import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.ModuleInfo; +import android.content.pm.PackageManager; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -55,6 +60,8 @@ public class SpecialAppAccessPreferenceControllerTest { private ApplicationsState.Session mSession; @Mock private PreferenceScreen mScreen; + @Mock + private PackageManager mPackageManager; private SpecialAppAccessPreferenceController mController; private Preference mPreference; @@ -62,8 +69,11 @@ public class SpecialAppAccessPreferenceControllerTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = spy(RuntimeEnvironment.application); + when(mContext.getApplicationContext()).thenReturn(mContext); ShadowUserManager.getShadow().setProfileIdsWithDisabled(new int[]{0}); + doReturn(mPackageManager).when(mContext).getPackageManager(); + doReturn(new ArrayList()).when(mPackageManager).getInstalledModules(anyInt()); mController = new SpecialAppAccessPreferenceController(mContext, "test_key"); mPreference = new Preference(mContext); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java index e1913a2d304..32829755a62 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java @@ -18,11 +18,15 @@ package com.android.settings.fuelgauge; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.pm.ModuleInfo; +import android.content.pm.PackageManager; +import android.os.UserManager; import android.text.TextUtils; import android.text.format.DateUtils; @@ -34,6 +38,7 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.applications.ApplicationsState; import org.junit.Before; import org.junit.Test; @@ -42,6 +47,10 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.util.ReflectionHelpers; + +import java.util.ArrayList; +import java.util.List; @RunWith(RobolectricTestRunner.class) public class BatteryAppListPreferenceControllerTest { @@ -60,6 +69,10 @@ public class BatteryAppListPreferenceControllerTest { private InstrumentedPreferenceFragment mFragment; @Mock private BatteryUtils mBatteryUtils; + @Mock + private PackageManager mPackageManager; + @Mock + private UserManager mUserManager; private Context mContext; private PowerGaugePreference mPreference; @@ -70,6 +83,11 @@ public class BatteryAppListPreferenceControllerTest { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mContext.getApplicationContext()).thenReturn(mContext); + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {}); + FakeFeatureFactory.setupForTest(); mPreference = new PowerGaugePreference(mContext); @@ -183,6 +201,21 @@ public class BatteryAppListPreferenceControllerTest { assertThat(mPreferenceController.shouldHideSipper(mNormalBatterySipper)).isFalse(); } + @Test + public void testShouldHideSipper_hiddenSystemModule_returnTrue() { + ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", null); + final String packageName = "test.hidden.module"; + final ModuleInfo moduleInfo = new ModuleInfo(); + moduleInfo.setPackageName(packageName); + moduleInfo.setHidden(true); + final List modules = new ArrayList<>(); + modules.add(moduleInfo); + when(mBatteryUtils.getPackageName(anyInt() /* uid */)).thenReturn(packageName); + when(mPackageManager.getInstalledModules(anyInt() /* flags */)).thenReturn(modules); + + assertThat(mPreferenceController.shouldHideSipper(mNormalBatterySipper)).isTrue(); + } + @Test public void testNeverUseFakeData() { assertThat(BatteryAppListPreferenceController.USE_FAKE_DATA).isFalse();