From d646ad7778b9eb425c20e34db13370542ef932eb Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Tue, 26 Mar 2019 16:20:33 -0700 Subject: [PATCH] exit app info page if app is a hidden system module. Fixes: 120546598 Test: robotest Change-Id: I763ce9d65904e2b0c2a6144776c42881a1269c52 --- .../appinfo/AppInfoDashboardFragment.java | 24 +++++++- .../appinfo/AppInfoDashboardFragmentTest.java | 55 ++++++++++++++++++- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 4987286ed36..183d3843447 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -187,6 +187,9 @@ public class AppInfoDashboardFragment extends DashboardFragment if (!ensurePackageInfoAvailable(activity)) { return; } + if (!ensureDisplayableModule(activity)) { + return; + } startListeningToPackageRemove(); setHasOptionsMenu(true); @@ -260,8 +263,8 @@ public class AppInfoDashboardFragment extends DashboardFragment new InstantAppButtonsPreferenceController(context, this, packageName, lifecycle); controllers.add(mInstantAppButtonPreferenceController); mAppButtonsPreferenceController = new AppButtonsPreferenceController( - (SettingsActivity) getActivity(), this, lifecycle, packageName, mState, - REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN); + (SettingsActivity) getActivity(), this, lifecycle, packageName, mState, + REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN); controllers.add(mAppButtonsPreferenceController); controllers.add(new AppBatteryPreferenceController(context, this, packageName, lifecycle)); controllers.add(new AppMemoryPreferenceController(context, this, lifecycle)); @@ -318,6 +321,23 @@ public class AppInfoDashboardFragment extends DashboardFragment return true; } + /** + * Ensures the package is displayable as directed by {@link AppUtils#isHiddenSystemModule}. + * If it's not, the fragment will finish. + * + * @return true if package is displayable. + */ + @VisibleForTesting + boolean ensureDisplayableModule(Activity activity) { + if (AppUtils.isHiddenSystemModule(activity.getApplicationContext(), mPackageName)) { + mFinishing = true; + Log.w(TAG, "Package is hidden module, exiting: " + mPackageName); + activity.finishAndRemoveTask(); + return false; + } + return true; + } + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); 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 9e44c955ed9..56e59f7bd0e 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java @@ -17,8 +17,7 @@ package com.android.settings.applications.appinfo; import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.ARG_PACKAGE_NAME; -import static com.android.settings.applications.appinfo.AppInfoDashboardFragment - .UNINSTALL_ALL_USERS_MENU; +import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_ALL_USERS_MENU; import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_UPDATES; import static com.google.common.truth.Truth.assertThat; @@ -43,6 +42,7 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Bundle; import android.os.UserManager; +import android.util.ArraySet; import android.view.Menu; import android.view.MenuItem; @@ -53,6 +53,7 @@ import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.instantapps.InstantAppDataProvider; import com.android.settingslib.core.lifecycle.Lifecycle; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -63,10 +64,14 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.annotation.Resetter; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; +import java.util.Set; @RunWith(RobolectricTestRunner.class) public final class AppInfoDashboardFragmentTest { @@ -101,6 +106,11 @@ public final class AppInfoDashboardFragmentTest { (InstantAppDataProvider) (i -> false)); } + @After + public void tearDown() { + ShadowAppUtils.reset(); + } + @Test public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() { when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false); @@ -186,6 +196,24 @@ public final class AppInfoDashboardFragmentTest { verify(mActivity, never()).finishAndRemoveTask(); } + @Test + @Config(shadows = ShadowAppUtils.class) + public void ensureDisplayableModule_hiddenModule_shouldReturnFalse() { + ShadowAppUtils.addHiddenModule(PACKAGE_NAME); + ReflectionHelpers.setField(mFragment, "mPackageName", PACKAGE_NAME); + + + assertThat(mFragment.ensureDisplayableModule(mActivity)).isFalse(); + } + + @Test + @Config(shadows = ShadowAppUtils.class) + public void ensureDisplayableModule_regularApp_shouldReturnTrue() { + ReflectionHelpers.setField(mFragment, "mPackageName", PACKAGE_NAME); + + assertThat(mFragment.ensureDisplayableModule(mActivity)).isTrue(); + } + @Test public void createPreference_hasNoPackageInfo_shouldSkip() { ReflectionHelpers.setField(mFragment, "mPackageInfo", null); @@ -240,7 +268,8 @@ public final class AppInfoDashboardFragmentTest { doReturn(true).when(mFragment).refreshUi(); mFragment - .onActivityResult(AppInfoDashboardFragment.REQUEST_UNINSTALL, 0, mock(Intent.class)); + .onActivityResult(AppInfoDashboardFragment.REQUEST_UNINSTALL, 0, + mock(Intent.class)); verify(mActivity).invalidateOptionsMenu(); } @@ -347,4 +376,24 @@ public final class AppInfoDashboardFragmentTest { .containsKey(ARG_PACKAGE_NAME)) .isTrue(); } + + @Implements(AppUtils.class) + public static class ShadowAppUtils { + + public static Set sHiddenModules = new ArraySet<>(); + + @Resetter + public static void reset() { + sHiddenModules.clear(); + } + + public static void addHiddenModule(String pkg) { + sHiddenModules.add(pkg); + } + + @Implementation + protected static boolean isHiddenSystemModule(Context context, String packageName) { + return sHiddenModules.contains(packageName); + } + } }