Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62b15ac6 authored by Yanting Yang's avatar Yanting Yang
Browse files

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
parent 37d5ed50
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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);
        }
    }
+3 −1
Original line number Diff line number Diff line
@@ -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));
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -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;
        }

+50 −3
Original line number Diff line number Diff line
@@ -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());
        }
    }
}
+24 −0
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
Loading