Update App info behavior for mainline module
As requested by framework team, the mainline module should be considered as system apps and not stoppable and disable-able. Since many of these modules provide critical functionality, disabling them can result in a very unstable device. According to the request, Settings will apply below changes to App info page for protecting mainline modules: - Hide "Force stop" and "Disable" in App info. - Disable "Clear storage" and "Clear cache" in "Storage & cache". Since the mainline module checking API interface changed, also change the dependent files and test cases. Fixes: 156955322 Test: robotest and verify "Cell Broadcast Service" in App info Change-Id: Ibc239bdaf3364eda541a33add382364cfdc6fc9b
This commit is contained in:
@@ -54,6 +54,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.deviceinfo.StorageWizardMoveConfirm;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState.Callbacks;
|
||||
import com.android.settingslib.applications.StorageStatsSource;
|
||||
import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
|
||||
@@ -321,7 +322,7 @@ public class AppStorageSettings extends AppInfoWithHeader
|
||||
.setButton1OnClickListener(v -> handleClearDataClick());
|
||||
}
|
||||
|
||||
if (mAppsControlDisallowedBySystem) {
|
||||
if (mAppsControlDisallowedBySystem || AppUtils.isMainlineModule(mPm, mPackageName)) {
|
||||
mButtonsPref.setButton1Enabled(false);
|
||||
}
|
||||
}
|
||||
@@ -579,7 +580,7 @@ public class AppStorageSettings extends AppInfoWithHeader
|
||||
.setButton2OnClickListener(v -> handleClearCacheClick());
|
||||
}
|
||||
}
|
||||
if (mAppsControlDisallowedBySystem) {
|
||||
if (mAppsControlDisallowedBySystem || AppUtils.isMainlineModule(mPm, mPackageName)) {
|
||||
mButtonsPref.setButton1Enabled(false).setButton2Enabled(false);
|
||||
}
|
||||
}
|
||||
|
@@ -744,7 +744,9 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp
|
||||
}
|
||||
|
||||
private boolean isSystemModule() {
|
||||
return mAppEntry != null && AppUtils.isSystemModule(mContext, mAppEntry.info.packageName);
|
||||
return mAppEntry != null
|
||||
&& (AppUtils.isSystemModule(mContext, mAppEntry.info.packageName)
|
||||
|| AppUtils.isMainlineModule(mPm, mAppEntry.info.packageName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -43,7 +43,7 @@ public class AppInstallerInfoPreferenceController extends AppInfoPreferenceContr
|
||||
return DISABLED_FOR_USER;
|
||||
}
|
||||
|
||||
if (AppUtils.isMainlineModule(mContext, mPackageName)) {
|
||||
if (AppUtils.isMainlineModule(mContext.getPackageManager(), mPackageName)) {
|
||||
return DISABLED_FOR_USER;
|
||||
}
|
||||
|
||||
|
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -28,6 +28,10 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ModuleInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
@@ -51,6 +55,8 @@ public class AppStorageSettingsTest {
|
||||
private AppStorageSettings mSettings;
|
||||
private Button mLeftButton;
|
||||
private Button mRightButton;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -58,6 +64,8 @@ public class AppStorageSettingsTest {
|
||||
mLeftButton = new Button(RuntimeEnvironment.application);
|
||||
mRightButton = new Button(RuntimeEnvironment.application);
|
||||
mSettings = spy(new AppStorageSettings());
|
||||
mSettings.mPm = mPackageManager;
|
||||
mSettings.mPackageName = "Package";
|
||||
mSettings.mSizeController = mSizesController;
|
||||
mButtonsPref = createMock();
|
||||
mSettings.mButtonsPref = mButtonsPref;
|
||||
@@ -77,7 +85,9 @@ public class AppStorageSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiWithSize_noAppStats_shouldDisableClearButtons() {
|
||||
public void updateUiWithSize_noAppStats_shouldDisableClearButtons()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
mockMainlineModule(mSettings.mPackageName, false /* isMainlineModule */);
|
||||
mSettings.updateUiWithSize(null);
|
||||
|
||||
verify(mSizesController).updateUi(nullable(Context.class));
|
||||
@@ -86,12 +96,15 @@ public class AppStorageSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiWithSize_hasDataAndCache_shouldEnableClearButtons() {
|
||||
public void updateUiWithSize_hasDataAndCache_shouldEnableClearButtons()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final AppStorageStats stats = mock(AppStorageStats.class);
|
||||
when(stats.getCacheBytes()).thenReturn(5000L);
|
||||
when(stats.getDataBytes()).thenReturn(10000L);
|
||||
doNothing().when(mSettings).handleClearCacheClick();
|
||||
doNothing().when(mSettings).handleClearDataClick();
|
||||
mockMainlineModule(mSettings.mPackageName, false /* isMainlineModule */);
|
||||
|
||||
|
||||
mSettings.updateUiWithSize(stats);
|
||||
verify(mButtonsPref).setButton1Enabled(true);
|
||||
@@ -105,6 +118,22 @@ public class AppStorageSettingsTest {
|
||||
verify(mSettings).handleClearCacheClick();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUiWithSize_mainlineModule_shouldDisableClearButtons()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final AppStorageStats stats = mock(AppStorageStats.class);
|
||||
when(stats.getCacheBytes()).thenReturn(5000L);
|
||||
when(stats.getDataBytes()).thenReturn(10000L);
|
||||
doNothing().when(mSettings).handleClearCacheClick();
|
||||
doNothing().when(mSettings).handleClearDataClick();
|
||||
mockMainlineModule(mSettings.mPackageName, true /* isMainlineModule */);
|
||||
|
||||
|
||||
mSettings.updateUiWithSize(stats);
|
||||
verify(mButtonsPref).setButton1Enabled(false);
|
||||
verify(mButtonsPref).setButton2Enabled(false);
|
||||
}
|
||||
|
||||
private ActionButtonsPreference createMock() {
|
||||
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
|
||||
when(pref.setButton1Text(anyInt())).thenReturn(pref);
|
||||
@@ -121,5 +150,23 @@ public class AppStorageSettingsTest {
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
private void mockMainlineModule(String packageName, boolean isMainlineModule)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final PackageInfo packageInfo = new PackageInfo();
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.sourceDir = "apex";
|
||||
packageInfo.applicationInfo = applicationInfo;
|
||||
|
||||
if (isMainlineModule) {
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
new ModuleInfo());
|
||||
} else {
|
||||
when(mPackageManager.getPackageInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
packageInfo);
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenThrow(
|
||||
new PackageManager.NameNotFoundException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -543,6 +543,19 @@ public class AppButtonsPreferenceControllerTest {
|
||||
assertThat(i.getBooleanExtra(KEY_REMOVE_TASK_WHEN_FINISHING, false)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowAppUtils.class)
|
||||
public void isAvailable_nonMainlineModule_isTrue() {
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowAppUtils.class)
|
||||
public void isAvailable_mainlineModule_isFalse() {
|
||||
ShadowAppUtils.addMainlineModule(mController.mPackageName);
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* The test fragment which implements
|
||||
* {@link ButtonActionDialogFragment.AppButtonsDialogListener}
|
||||
@@ -597,16 +610,22 @@ public class AppButtonsPreferenceControllerTest {
|
||||
public static class ShadowAppUtils {
|
||||
|
||||
public static Set<String> sSystemModules = new ArraySet<>();
|
||||
public static Set<String> sMainlineModules = new ArraySet<>();
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sSystemModules.clear();
|
||||
sMainlineModules.clear();
|
||||
}
|
||||
|
||||
public static void addHiddenModule(String pkg) {
|
||||
sSystemModules.add(pkg);
|
||||
}
|
||||
|
||||
public static void addMainlineModule(String pkg) {
|
||||
sMainlineModules.add(pkg);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isInstant(ApplicationInfo info) {
|
||||
return false;
|
||||
@@ -616,5 +635,10 @@ public class AppButtonsPreferenceControllerTest {
|
||||
protected static boolean isSystemModule(Context context, String packageName) {
|
||||
return sSystemModules.contains(packageName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isMainlineModule(PackageManager pm, String packageName) {
|
||||
return sMainlineModules.contains(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -99,12 +99,15 @@ public class AppInstallerInfoPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_hasAppLabel_shouldReturnAvailable() {
|
||||
public void getAvailabilityStatus_hasAppLabel_shouldReturnAvailable()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final String packageName = "Package1";
|
||||
when(mUserManager.isManagedProfile()).thenReturn(false);
|
||||
when(mAppInfo.loadLabel(mPackageManager)).thenReturn("Label1");
|
||||
mController = new AppInstallerInfoPreferenceController(mContext, "test_key");
|
||||
mController.setPackageName("Package1");
|
||||
mController.setPackageName(packageName);
|
||||
mController.setParentFragment(mFragment);
|
||||
mockMainlineModule(packageName, false /* isMainlineModule */);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
@@ -153,12 +156,31 @@ public class AppInstallerInfoPreferenceControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_isMainlineModule_shouldReturnDisabled()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final String packageName = "Package";
|
||||
when(mUserManager.isManagedProfile()).thenReturn(false);
|
||||
when(mAppInfo.loadLabel(mPackageManager)).thenReturn("Label");
|
||||
mController.setPackageName("Package");
|
||||
when(mPackageManager.getModuleInfo("Package", 0 /* flags */)).thenReturn(new ModuleInfo());
|
||||
mController.setPackageName(packageName);
|
||||
mockMainlineModule(packageName, true /* isMainlineModule */);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.DISABLED_FOR_USER);
|
||||
}
|
||||
|
||||
private void mockMainlineModule(String packageName, boolean isMainlineModule)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final PackageInfo packageInfo = new PackageInfo();
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.sourceDir = "apex";
|
||||
packageInfo.applicationInfo = applicationInfo;
|
||||
|
||||
if (isMainlineModule) {
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
new ModuleInfo());
|
||||
} else {
|
||||
when(mPackageManager.getPackageInfo(packageName, 0 /* flags */)).thenReturn(
|
||||
packageInfo);
|
||||
when(mPackageManager.getModuleInfo(packageName, 0 /* flags */)).thenThrow(
|
||||
new PackageManager.NameNotFoundException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user