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

Commit 724e36e3 authored by Kiran S's avatar Kiran S Committed by Cherrypicker Worker
Browse files

Restrict USB poups while setup is in progress

Test: Manually verified that USB popups are not displayed while setup is
in progress. atest UsbManagerTests.
Bug: 332757346
Flag: com.android.server.usb.flags.allow_restriction_of_overlay_activities
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:76feb3795672beacbc534683825bb7f871157e2f)
Merged-In: I7de666b9c807f0458bf0df291bab4da2cb98f886
Change-Id: I7de666b9c807f0458bf0df291bab4da2cb98f886
24D1-dev is based on 24Q2-release. Therefore, we merged this CL to 24D1-dev.
parent e2e01571
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.usb;

import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;

import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;

import android.Manifest;
@@ -43,6 +45,7 @@ import android.os.AsyncTask;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.usb.UsbProfileGroupSettingsManagerProto;
import android.service.usb.UsbSettingsAccessoryPreferenceProto;
import android.service.usb.UsbSettingsDevicePreferenceProto;
@@ -939,13 +942,24 @@ public class UsbProfileGroupSettingsManager {
    }

    /**
     * @return true if any application in foreground have set restrict_usb_overlay_activities as
     * true in manifest file. The application needs to have MANAGE_USB permission.
     * @return true if the user has not finished the setup process or if there are any
     * foreground applications with MANAGE_USB permission and restrict_usb_overlay_activities
     * enabled in the manifest file.
     */
    private boolean shouldRestrictOverlayActivities() {

        if (!Flags.allowRestrictionOfOverlayActivities()) return false;

        if (Settings.Secure.getIntForUser(
                mContext.getContentResolver(),
                USER_SETUP_COMPLETE,
                /* defaultValue= */ 1,
                UserHandle.CURRENT.getIdentifier())
                == 0) {
            Slog.d(TAG, "restricting usb overlay activities as setup is not complete");
            return true;
        }

        List<ActivityManager.RunningAppProcessInfo> appProcessInfos = mActivityManager
                .getRunningAppProcesses();

+3 −0
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ android_test {
        "libmultiplejvmtiagentsinterferenceagent",
        "libstaticjvmtiagent",
    ],
    libs: [
        "android.test.mock",
    ],
    certificate: "platform",
    platform_apis: true,
    test_suites: ["device-tests"],
+100 −65
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.usbtest;

import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;

import static com.android.server.usb.UsbProfileGroupSettingsManager.PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES;

import static org.mockito.ArgumentMatchers.any;
@@ -32,16 +34,20 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager.Property;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.hardware.usb.UsbDevice;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.test.mock.MockContentResolver;

import androidx.test.runner.AndroidJUnit4;

import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.usb.UsbHandlerManager;
import com.android.server.usb.UsbProfileGroupSettingsManager;
import com.android.server.usb.UsbSettingsManager;
@@ -69,6 +75,7 @@ import java.util.List;
public class UsbProfileGroupSettingsManagerTest {

    private static final String TEST_PACKAGE_NAME = "testPkg";

    @Mock
    private Context mContext;
    @Mock
@@ -85,43 +92,78 @@ public class UsbProfileGroupSettingsManagerTest {
    private UserManager mUserManager;
    @Mock
    private UsbUserSettingsManager mUsbUserSettingsManager;
    @Mock private Property mProperty;
    private ActivityManager.RunningAppProcessInfo mRunningAppProcessInfo;
    private PackageInfo mPackageInfo;
    private UsbProfileGroupSettingsManager mUsbProfileGroupSettingsManager;
    @Mock
    private Property mRestrictUsbOverlayActivitiesProperty;
    @Mock
    private UsbDevice mUsbDevice;

    private MockContentResolver mContentResolver;
    private MockitoSession mStaticMockSession;

    private UsbProfileGroupSettingsManager mUsbProfileGroupSettingsManager;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mStaticMockSession = ExtendedMockito.mockitoSession()
                .mockStatic(Flags.class)
                .strictness(Strictness.WARN)
                .startMocking();

        mRunningAppProcessInfo = new ActivityManager.RunningAppProcessInfo();
        mRunningAppProcessInfo.pkgList = new String[]{TEST_PACKAGE_NAME};
        mPackageInfo = new PackageInfo();
        mPackageInfo.packageName = TEST_PACKAGE_NAME;
        mPackageInfo.applicationInfo = Mockito.mock(ApplicationInfo.class);
        when(mUsbSettingsManager.getSettingsForUser(anyInt())).thenReturn(mUsbUserSettingsManager);
        when(mUserManager.getEnabledProfiles(anyInt()))
                .thenReturn(List.of(Mockito.mock(UserInfo.class)));

        mContentResolver = new MockContentResolver();
        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());

        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
        when(mContext.getResources()).thenReturn(Mockito.mock(Resources.class));
        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
        when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
        when(mContext.createPackageContextAsUser(anyString(), anyInt(), any(UserHandle.class)))
                .thenReturn(mContext);
        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);

        mUsbProfileGroupSettingsManager = new UsbProfileGroupSettingsManager(mContext, mUserHandle,
                mUsbSettingsManager, mUsbHandlerManager);
        mUsbProfileGroupSettingsManager = new UsbProfileGroupSettingsManager(
                mContext, mUserHandle, mUsbSettingsManager, mUsbHandlerManager);

        mStaticMockSession = ExtendedMockito.mockitoSession()
                .mockStatic(Flags.class)
                .strictness(Strictness.WARN)
                .startMocking();
        setupDefaultConfiguration();
    }

    /**
     * Setups the following configuration
     *
     * <ul>
     * <li>Flag is enabled
     * <li>Device setup has completed
     * <li>There is a foreground activity with MANAGE_USB permission
     * <li>The foreground activity has PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES enabled
     * </ul>
     */
    private void setupDefaultConfiguration() throws NameNotFoundException {
        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);

        Settings.Secure.putInt(mContentResolver, USER_SETUP_COMPLETE, 1);

        ActivityManager.RunningAppProcessInfo mRunningAppProcessInfo =
                new ActivityManager.RunningAppProcessInfo();
        mRunningAppProcessInfo.pkgList = new String[] { TEST_PACKAGE_NAME };
        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));

        PackageInfo mPackageInfo = new PackageInfo();
        mPackageInfo.packageName = TEST_PACKAGE_NAME;
        mPackageInfo.applicationInfo = Mockito.mock(ApplicationInfo.class);
        when(mPackageManager.getPackageInfo(TEST_PACKAGE_NAME, 0)).thenReturn(mPackageInfo);
        when(mPackageManager.getProperty(eq(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES),
                eq(TEST_PACKAGE_NAME))).thenReturn(mProperty);
        when(mUserManager.getEnabledProfiles(anyInt()))
                .thenReturn(List.of(Mockito.mock(UserInfo.class)));
        when(mUsbSettingsManager.getSettingsForUser(anyInt())).thenReturn(mUsbUserSettingsManager);
        when(mPackageManager.getPackagesHoldingPermissions(
                new String[] { android.Manifest.permission.MANAGE_USB },
                PackageManager.MATCH_SYSTEM_ONLY))
                .thenReturn(List.of(mPackageInfo));

        when(mRestrictUsbOverlayActivitiesProperty.getBoolean()).thenReturn(true);
        when(mPackageManager.getProperty(
                eq(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES), eq(TEST_PACKAGE_NAME)))
                .thenReturn(mRestrictUsbOverlayActivitiesProperty);
    }

    @After
@@ -130,66 +172,59 @@ public class UsbProfileGroupSettingsManagerTest {
    }

    @Test
    public void testDeviceAttached_flagTrueWithoutForegroundActivity_resolveActivityCalled() {
        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
    public void testDeviceAttached_foregroundActivityWithManifestField_resolveActivityNotCalled() {
        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);

        verify(mUsbUserSettingsManager, times(0)).queryIntentActivities(any(Intent.class));
    }

    @Test
    public void testDeviceAttached_noForegroundActivity_resolveActivityCalled() {
        when(mActivityManager.getRunningAppProcesses()).thenReturn(new ArrayList<>());
        when(mPackageManager.getPackagesHoldingPermissions(
                new String[]{android.Manifest.permission.MANAGE_USB},
                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
        UsbDevice device = Mockito.mock(UsbDevice.class);
        mUsbProfileGroupSettingsManager.deviceAttached(device);

        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);

        verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
    }

    @Test
    public void testDeviceAttached_noForegroundActivityWithUsbPermission_resolveActivityCalled() {
        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
        when(mPackageManager.getPackagesHoldingPermissions(
                new String[] { android.Manifest.permission.MANAGE_USB },
                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(new ArrayList<>());
        UsbDevice device = Mockito.mock(UsbDevice.class);
        mUsbProfileGroupSettingsManager.deviceAttached(device);
                PackageManager.MATCH_SYSTEM_ONLY))
                .thenReturn(new ArrayList<>());

        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);

        verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
    }

    @Test
    public void testDeviceAttached_foregroundActivityWithManifestField_resolveActivityNotCalled() {
        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
        when(mProperty.getBoolean()).thenReturn(true);
        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
        when(mPackageManager.getPackagesHoldingPermissions(
                new String[]{android.Manifest.permission.MANAGE_USB},
                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
        UsbDevice device = Mockito.mock(UsbDevice.class);
        mUsbProfileGroupSettingsManager.deviceAttached(device);
        verify(mUsbUserSettingsManager, times(0))
                .queryIntentActivities(any(Intent.class));
    }
    public void testDeviceAttached_restricUsbOverlayPropertyDisabled_resolveActivityCalled() {
        when(mRestrictUsbOverlayActivitiesProperty.getBoolean()).thenReturn(false);

        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);

    @Test
    public void testDeviceAttached_foregroundActivityWithoutManifestField_resolveActivityCalled() {
        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
        when(mProperty.getBoolean()).thenReturn(false);
        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
        when(mPackageManager.getPackagesHoldingPermissions(
                new String[]{android.Manifest.permission.MANAGE_USB},
                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
        UsbDevice device = Mockito.mock(UsbDevice.class);
        mUsbProfileGroupSettingsManager.deviceAttached(device);
        verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
    }

    @Test
    public void testDeviceAttached_flagFalseForegroundActivity_resolveActivityCalled() {
    public void testDeviceAttached_flagFalse_resolveActivityCalled() {
        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(false);
        when(mProperty.getBoolean()).thenReturn(true);
        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
        when(mPackageManager.getPackagesHoldingPermissions(
                new String[]{android.Manifest.permission.MANAGE_USB},
                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
        UsbDevice device = Mockito.mock(UsbDevice.class);
        mUsbProfileGroupSettingsManager.deviceAttached(device);

        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);

        verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
    }

    @Test
    public void
            testDeviceAttached_setupNotCompleteAndNoBlockingActivities_resolveActivityNotCalled() {
        when(mRestrictUsbOverlayActivitiesProperty.getBoolean()).thenReturn(false);
        Settings.Secure.putInt(mContentResolver, USER_SETUP_COMPLETE, 0);

        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);

        verify(mUsbUserSettingsManager, times(0)).queryIntentActivities(any(Intent.class));
    }
}