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

Commit a931fcdc authored by mrulhania's avatar mrulhania
Browse files

Exempt autofill service to record sensitive content

Bug: 328251279
Test: atest SensitiveContentProtectionManagerServiceContentTest
Change-Id: I679ba211c2ff5df49d28810bec0006487b7d9855
parent 99bd6d45
Loading
Loading
Loading
Loading
+35 −16
Original line number Diff line number Diff line
@@ -161,20 +161,20 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
        }

        if (DEBUG) Log.d(TAG, "onBootPhase - PHASE_BOOT_COMPLETED");

        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        init(getContext().getSystemService(MediaProjectionManager.class),
                LocalServices.getService(WindowManagerInternal.class),
                getExemptedPackages());
                LocalServices.getService(PackageManagerInternal.class),
                getExemptedPackages()
        );
        if (sensitiveContentAppProtection()) {
            publishBinderService(Context.SENSITIVE_CONTENT_PROTECTION_SERVICE,
                    new SensitiveContentProtectionManagerServiceBinder(mPackageManagerInternal));
                    new SensitiveContentProtectionManagerServiceBinder());
        }
    }

    @VisibleForTesting
    void init(MediaProjectionManager projectionManager, WindowManagerInternal windowManager,
            ArraySet<String> exemptedPackages) {
            PackageManagerInternal packageManagerInternal, ArraySet<String> exemptedPackages) {
        if (DEBUG) Log.d(TAG, "init");

        Objects.requireNonNull(projectionManager);
@@ -182,6 +182,7 @@ public final class SensitiveContentProtectionManagerService extends SystemServic

        mProjectionManager = projectionManager;
        mWindowManager = windowManager;
        mPackageManagerInternal = packageManagerInternal;
        mExemptedPackages = exemptedPackages;

        // TODO(b/317250444): use MediaProjectionManagerService directly, reduces unnecessary
@@ -231,14 +232,16 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
    }

    private void onProjectionStart(MediaProjectionInfo projectionInfo) {
        int uid = mPackageManagerInternal.getPackageUid(projectionInfo.getPackageName(), 0,
                projectionInfo.getUserHandle().getIdentifier());
        boolean isPackageExempted = (mExemptedPackages != null && mExemptedPackages.contains(
                projectionInfo.getPackageName()))
                || canRecordSensitiveContent(projectionInfo.getPackageName());
                || canRecordSensitiveContent(projectionInfo.getPackageName())
                || isAutofillServiceRecorderPackage(projectionInfo.getUserHandle().getIdentifier(),
                        projectionInfo.getPackageName());
        // TODO(b/324447419): move GlobalSettings lookup to background thread
        boolean isFeatureDisabled = Settings.Global.getInt(getContext().getContentResolver(),
                DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 0) != 0;
        int uid = mPackageManagerInternal.getPackageUid(projectionInfo.getPackageName(), 0,
                projectionInfo.getUserHandle().getIdentifier());
        mMediaProjectionSession = new MediaProjectionSession(
                uid, isPackageExempted || isFeatureDisabled, new Random().nextLong());

@@ -295,9 +298,10 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
        // notify windowmanager of any currently posted sensitive content notifications
        ArraySet<PackageInfo> packageInfos =
                getSensitivePackagesFromNotifications(notifications, rankingMap);

        if (packageInfos.size() > 0) {
            mWindowManager.addBlockScreenCaptureForApps(packageInfos);
        }
    }

    private ArraySet<PackageInfo> getSensitivePackagesFromNotifications(
            @NonNull StatusBarNotification[] notifications, RankingMap rankingMap) {
@@ -422,6 +426,7 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
            if (!mProjectionActive) {
                return;
            }

            if (DEBUG) {
                Log.d(TAG, "setSensitiveContentProtection - current package=" + packageInfo
                        + ", isShowingSensitiveContent=" + isShowingSensitiveContent
@@ -452,15 +457,29 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
        }
    }

    private final class SensitiveContentProtectionManagerServiceBinder
            extends ISensitiveContentProtectionManager.Stub {
        private final PackageManagerInternal mPackageManagerInternal;
    // TODO: b/328251279 - Autofill service exemption is temporary and will be removed in future.
    private boolean isAutofillServiceRecorderPackage(int userId, String projectionPackage) {
        String autofillServiceName = Settings.Secure.getStringForUser(
                getContext().getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, userId);
        if (DEBUG) {
            Log.d(TAG, "autofill service for user " + userId + " is " + autofillServiceName);
        }

        SensitiveContentProtectionManagerServiceBinder(
                PackageManagerInternal packageManagerInternal) {
            mPackageManagerInternal = packageManagerInternal;
        if (autofillServiceName == null) {
            return false;
        }
        ComponentName serviceComponent = ComponentName.unflattenFromString(autofillServiceName);
        if (serviceComponent == null) {
            return false;
        }
        String autofillServicePackage = serviceComponent.getPackageName();

        return autofillServicePackage != null
                && autofillServicePackage.equals(projectionPackage);
    }

    private final class SensitiveContentProtectionManagerServiceBinder
            extends ISensitiveContentProtectionManager.Stub {
        public void setSensitiveContentProtection(IBinder windowToken, String packageName,
                boolean isShowingSensitiveContent) {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
+18 −1
Original line number Diff line number Diff line
@@ -24,9 +24,11 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.content.pm.PackageManagerInternal;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
import android.os.Binder;
@@ -72,6 +74,7 @@ public class SensitiveContentProtectionManagerServiceContentTest {

    @Mock private WindowManagerInternal mWindowManager;
    @Mock private MediaProjectionManager mProjectionManager;
    @Mock private PackageManagerInternal mPackageManagerInternal;
    private MediaProjectionInfo mMediaProjectionInfo;

    @Captor
@@ -91,7 +94,7 @@ public class SensitiveContentProtectionManagerServiceContentTest {
        mSensitiveContentProtectionManagerService =
                new SensitiveContentProtectionManagerService(mContext);
        mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager,
                new ArraySet<>(Set.of(mExemptedScreenRecorderPackage)));
                mPackageManagerInternal, new ArraySet<>(Set.of(mExemptedScreenRecorderPackage)));
        verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any());
        mMediaPorjectionCallback = mMediaProjectionCallbackCaptor.getValue();
        mMediaProjectionInfo =
@@ -145,6 +148,20 @@ public class SensitiveContentProtectionManagerServiceContentTest {
        verify(mWindowManager).clearBlockedApps();
    }

    @Test
    public void testAutofillServicePackageExemption() {
        String testAutofillService = mScreenRecorderPackage + "/com.example.SampleAutofillService";
        int userId = Process.myUserHandle().getIdentifier();
        Settings.Secure.putStringForUser(mContext.getContentResolver(),
                Settings.Secure.AUTOFILL_SERVICE, testAutofillService , userId);

        mMediaPorjectionCallback.onStart(mMediaProjectionInfo);
        mSensitiveContentProtectionManagerService.setSensitiveContentProtection(
                mPackageInfo.getWindowToken(), mPackageInfo.getPkg(), mPackageInfo.getUid(), true);
        verify(mWindowManager, never())
                .addBlockScreenCaptureForApps(mPackageInfoCaptor.capture());
    }

    @Test
    public void testDeveloperOptionDisableFeature() {
        mockDisabledViaDeveloperOption();
+5 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.content.pm.PackageManagerInternal;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -103,6 +104,9 @@ public class SensitiveContentProtectionManagerServiceNotificationTest {
    @Mock
    private WindowManagerInternal mWindowManager;

    @Mock
    private PackageManagerInternal mPackageManagerInternal;

    @Mock
    private StatusBarNotification mNotification1;

@@ -141,7 +145,7 @@ public class SensitiveContentProtectionManagerServiceNotificationTest {
        setupSensitiveNotification();

        mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager,
                new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE)));
                mPackageManagerInternal, new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE)));

        // Obtain useful mMediaProjectionCallback
        verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any());