From bba02d88a4661f83384f74d2a16dd0c8b5d36949 Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Thu, 8 Feb 2018 15:53:16 -0800 Subject: [PATCH] Introduce config_disable_uninstall_update flag. This adds the following flag: config_disable_uninstall_update Which by default is false. When set to true, it will hide the "Uninstall updates" menu item for all cases. This is useful for cases where the device OEMs want to allow users to install apps, but do not want the ability to roll back updates on system applications. Bug: 62379281 Test: make RunSettingsRoboTests ROBOTEST_FILTER=AppInfoDashboardFragmentTest Change-Id: I55fe92467ca95c05f6682174c117031d8295790e --- res/values/bools.xml | 3 ++ .../appinfo/AppInfoDashboardFragment.java | 9 ++-- tests/robotests/res/values-mcc999/config.xml | 1 + .../appinfo/AppInfoDashboardFragmentTest.java | 43 +++++++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/res/values/bools.xml b/res/values/bools.xml index 0cf085f9cff..f20b93c0675 100644 --- a/res/values/bools.xml +++ b/res/values/bools.xml @@ -173,4 +173,7 @@ true + + + false diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 5790d34a478..5e12503ddaf 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -82,8 +82,8 @@ public class AppInfoDashboardFragment extends DashboardFragment private static final String TAG = "AppInfoDashboard"; // Menu identifiers - private static final int UNINSTALL_ALL_USERS_MENU = 1; - private static final int UNINSTALL_UPDATES = 2; + @VisibleForTesting static final int UNINSTALL_ALL_USERS_MENU = 1; + @VisibleForTesting static final int UNINSTALL_UPDATES = 2; static final int FORCE_STOP_MENU = 3; // Result code identifiers @@ -330,7 +330,10 @@ public class AppInfoDashboardFragment extends DashboardFragment menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry)); mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES); - uninstallUpdatesItem.setVisible(mUpdatedSysApp && !mAppsControlDisallowedBySystem); + final boolean uninstallUpdateDisabled = getContext().getResources().getBoolean( + R.bool.config_disable_uninstall_update); + uninstallUpdatesItem.setVisible( + mUpdatedSysApp && !mAppsControlDisallowedBySystem && !uninstallUpdateDisabled); if (uninstallUpdatesItem.isVisible()) { RestrictedLockUtils.setMenuItemAsDisabledByAdmin(getActivity(), uninstallUpdatesItem, mAppsControlDisallowedAdmin); diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml index f43e39c74e8..01bfa51b03e 100644 --- a/tests/robotests/res/values-mcc999/config.xml +++ b/tests/robotests/res/values-mcc999/config.xml @@ -62,4 +62,5 @@ false false false + true 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 b7e414c9a78..d721e17459f 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java @@ -16,6 +16,10 @@ package com.android.settings.applications.appinfo; +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; import static org.mockito.ArgumentMatchers.any; @@ -25,6 +29,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -36,6 +41,8 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.UserManager; +import android.view.Menu; +import android.view.MenuItem; import com.android.settings.SettingsActivity; import com.android.settings.TestConfig; @@ -128,6 +135,42 @@ public final class AppInfoDashboardFragmentTest { assertThat(mFragment.shouldShowUninstallForAll(appEntry)).isFalse(); } + @Test + public void onPrepareOptionsMenu_setUpdateMenuVisible_byDefaultForSystemApps_shouldBeTrue() { + Menu menu = onPrepareOptionsMenuTestsSetup(); + mFragment.onPrepareOptionsMenu(menu); + + verify(menu.findItem(UNINSTALL_UPDATES), times(1)).setVisible(true); + } + + @Test + @Config(qualifiers = "mcc999") + public void onPrepareOptionsMenu_setUpdateMenuVisible_ifDisabledByDevice_shouldBeFalse() { + Menu menu = onPrepareOptionsMenuTestsSetup(); + mFragment.onPrepareOptionsMenu(menu); + + verify(menu.findItem(UNINSTALL_UPDATES), times(1)).setVisible(false); + } + + private Menu onPrepareOptionsMenuTestsSetup() { + // Menu mocking + Menu menu = mock(Menu.class); + final MenuItem uninstallUpdatesMenuItem = mock(MenuItem.class); + final MenuItem uninstallForAllMenuItem = mock(MenuItem.class); + when(menu.findItem(UNINSTALL_UPDATES)).thenReturn(uninstallUpdatesMenuItem); + when(menu.findItem(UNINSTALL_ALL_USERS_MENU)).thenReturn(uninstallForAllMenuItem); + + // Setup work to prevent NPE + final ApplicationInfo info = new ApplicationInfo(); + info.flags = ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; + info.enabled = true; + final AppEntry appEntry = mock(AppEntry.class); + appEntry.info = info; + mFragment.setAppEntry(appEntry); + + return menu; + } + @Test public void launchFragment_hasNoPackageInfo_shouldFinish() { ReflectionHelpers.setField(mFragment, "mPackageInfo", null);