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

Commit 021ecf5c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Exempt autofill service to record sensitive content" into main

parents 1c982d0c a931fcdc
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());