Merge "exit app info page if app is a hidden system module."
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 4987286..183d384 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -187,6 +187,9 @@
if (!ensurePackageInfoAvailable(activity)) {
return;
}
+ if (!ensureDisplayableModule(activity)) {
+ return;
+ }
startListeningToPackageRemove();
setHasOptionsMenu(true);
@@ -260,8 +263,8 @@
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 @@
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 9e44c95..56e59f7 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.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.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.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 @@
(InstantAppDataProvider) (i -> false));
}
+ @After
+ public void tearDown() {
+ ShadowAppUtils.reset();
+ }
+
@Test
public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() {
when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
@@ -187,6 +197,24 @@
}
@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 @@
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 @@
.containsKey(ARG_PACKAGE_NAME))
.isTrue();
}
+
+ @Implements(AppUtils.class)
+ public static class ShadowAppUtils {
+
+ public static Set<String> 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);
+ }
+ }
}