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

Commit 381323ab authored by Manjeet Rulhania's avatar Manjeet Rulhania Committed by Android (Google) Code Review
Browse files

Merge "Add sensitive content protection during screen share" into main

parents 6f918e27 a296a14c
Loading
Loading
Loading
Loading
+105 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
import static android.view.flags.Flags.enableUseMeasureCacheDuringForceLayout;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
import static android.view.flags.Flags.viewVelocityApi;
@@ -135,6 +136,7 @@ import android.service.credentials.CredentialProviderService;
import android.sysprop.DisplayProperties;
import android.text.InputType;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatProperty;
@@ -3701,6 +3703,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *          1                       PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT
     *         1                        PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT
     *       11                         PFLAG4_CONTENT_SENSITIVITY_MASK
     *      1                           PFLAG4_IS_COUNTED_AS_SENSITIVE
     * |-------|-------|-------|-------|
     */
@@ -3826,6 +3829,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private static final int PFLAG4_CONTENT_SENSITIVITY_MASK =
            (CONTENT_SENSITIVITY_AUTO | CONTENT_SENSITIVITY_SENSITIVE
                    | CONTENT_SENSITIVITY_NOT_SENSITIVE) << PFLAG4_CONTENT_SENSITIVITY_SHIFT;
    /**
     * Whether this view has been counted as a sensitive view or not.
     *
     * @see AttachInfo#mSensitiveViewsCount
     */
    private static final int PFLAG4_IS_COUNTED_AS_SENSITIVE = 0x4000000;
    /* End of masks for mPrivateFlags4 */
    /** @hide */
@@ -10387,6 +10397,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        mPrivateFlags4 &= ~PFLAG4_CONTENT_SENSITIVITY_MASK;
        mPrivateFlags4 |= ((mode << PFLAG4_CONTENT_SENSITIVITY_SHIFT)
                & PFLAG4_CONTENT_SENSITIVITY_MASK);
        if (sensitiveContentAppProtection()) {
            updateSensitiveViewsCountIfNeeded(isAggregatedVisible());
        }
    }
    /**
@@ -10418,12 +10431,43 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    @FlaggedApi(FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API)
    public final boolean isContentSensitive() {
        if (getContentSensitivity() == CONTENT_SENSITIVITY_SENSITIVE) {
        final int contentSensitivity = getContentSensitivity();
        if (contentSensitivity == CONTENT_SENSITIVITY_SENSITIVE) {
            return true;
        } else if (contentSensitivity == CONTENT_SENSITIVITY_NOT_SENSITIVE) {
            return false;
        } else if (sensitiveContentAppProtection()) {
            return SensitiveAutofillHintsHelper
                    .containsSensitiveAutofillHint(getAutofillHints());
        }
        return false;
    }
    /**
     * Helper used to track sensitive views when they are added or removed from the window
     * based on whether it's laid out and visible.
     *
     * <p>This method is called from many places (visibility changed, view laid out, view attached
     * or detached to/from window, etc...)
     */
    private void updateSensitiveViewsCountIfNeeded(boolean appeared) {
        if (!sensitiveContentAppProtection() || mAttachInfo == null) {
            return;
        }
        if (appeared && isContentSensitive()) {
            if ((mPrivateFlags4 & PFLAG4_IS_COUNTED_AS_SENSITIVE) == 0) {
                mPrivateFlags4 |= PFLAG4_IS_COUNTED_AS_SENSITIVE;
                mAttachInfo.increaseSensitiveViewsCount();
            }
        } else {
            if ((mPrivateFlags4 & PFLAG4_IS_COUNTED_AS_SENSITIVE) != 0) {
                mPrivateFlags4 &= ~PFLAG4_IS_COUNTED_AS_SENSITIVE;
                mAttachInfo.decreaseSensitiveViewsCount();
            }
        }
    }
    /**
     * Gets the mode for determining whether this view is important for content capture.
     *
@@ -13457,6 +13501,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        } else {
            mAutofillHints = autofillHints;
        }
        if (sensitiveContentAppProtection()) {
            if (getContentSensitivity() == CONTENT_SENSITIVITY_AUTO) {
                updateSensitiveViewsCountIfNeeded(isAggregatedVisible());
            }
        }
    }
    /**
@@ -16681,6 +16730,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            }
            notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible);
            updateSensitiveViewsCountIfNeeded(isVisible);
            if (!getSystemGestureExclusionRects().isEmpty()) {
                postUpdate(this::updateSystemGestureExclusionRects);
@@ -22670,6 +22720,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(false);
        updateSensitiveViewsCountIfNeeded(false);
        mAttachInfo = null;
        if (mOverlay != null) {
@@ -31816,6 +31867,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         */
        ScrollCaptureInternal mScrollCaptureInternal;
        /**
         * sensitive views attached to the window
         */
        int mSensitiveViewsCount;
        /**
         * Creates a new set of attachment information with the specified
         * events handler and thread.
@@ -31835,6 +31891,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mTreeObserver = new ViewTreeObserver(context);
        }
        void increaseSensitiveViewsCount() {
            if (mSensitiveViewsCount == 0) {
                mViewRootImpl.notifySensitiveContentAppProtection(true);
            }
            mSensitiveViewsCount++;
        }
        void decreaseSensitiveViewsCount() {
            mSensitiveViewsCount--;
            if (mSensitiveViewsCount == 0) {
                mViewRootImpl.notifySensitiveContentAppProtection(false);
            }
            if (mSensitiveViewsCount < 0) {
                Log.wtf(VIEW_LOG_TAG, "mSensitiveViewsCount is negative" + mSensitiveViewsCount);
                mSensitiveViewsCount = 0;
            }
        }
        @Nullable
        ContentCaptureManager getContentCaptureManager(@NonNull Context context) {
            if (mContentCaptureManager != null) {
@@ -32448,6 +32522,36 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    private static class SensitiveAutofillHintsHelper {
        /**
         * List of autofill hints deemed sensitive for screen protection during screen share.
         */
        private static final ArraySet<String> SENSITIVE_CONTENT_AUTOFILL_HINTS = new ArraySet<>();
        static {
            SENSITIVE_CONTENT_AUTOFILL_HINTS.add(View.AUTOFILL_HINT_USERNAME);
            SENSITIVE_CONTENT_AUTOFILL_HINTS.add(View.AUTOFILL_HINT_PASSWORD_AUTO);
            SENSITIVE_CONTENT_AUTOFILL_HINTS.add(View.AUTOFILL_HINT_PASSWORD);
        }
        /**
         * Whether View's autofill hints contains a sensitive autofill hint.
         *
         * @see #SENSITIVE_CONTENT_AUTOFILL_HINTS
         */
        static boolean containsSensitiveAutofillHint(@Nullable String[] autofillHints) {
            if (autofillHints == null) {
                return false;
            }
            int size = autofillHints.length;
            for (int i = 0; i < size; i++) {
                if (SENSITIVE_CONTENT_AUTOFILL_HINTS.contains(autofillHints[i])) {
                    return true;
                }
            }
            return false;
        }
    }
    /**
     * Returns the current scroll capture hint for this view.
+34 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import static android.view.ViewRootImplProto.WIDTH;
import static android.view.ViewRootImplProto.WINDOW_ATTRIBUTES;
import static android.view.ViewRootImplProto.WIN_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
@@ -166,6 +167,7 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
@@ -924,6 +926,8 @@ public final class ViewRootImpl implements ViewParent,
    private IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection;
    private final ISensitiveContentProtectionManager mSensitiveContentProtectionService;
    static final class SystemUiVisibilityInfo {
        int globalVisibility;
        int localValue;
@@ -1203,6 +1207,13 @@ public final class ViewRootImpl implements ViewParent,
        mScrollCaptureRequestTimeout = SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS;
        mOnBackInvokedDispatcher = new WindowOnBackInvokedDispatcher(context);
        if (sensitiveContentAppProtection()) {
            mSensitiveContentProtectionService =
                    ISensitiveContentProtectionManager.Stub.asInterface(
                        ServiceManager.getService(Context.SENSITIVE_CONTENT_PROTECTION_SERVICE));
        } else {
            mSensitiveContentProtectionService = null;
        }
    }
    public static void addFirstDrawHandler(Runnable callback) {
@@ -4154,6 +4165,29 @@ public final class ViewRootImpl implements ViewParent,
        mWmsRequestSyncGroup.add(this, null /* runnable */);
    }
    /**
     * Helper used to notify the service to block projection when a sensitive
     * view (the view displays sensitive content) is attached to the window.
     * The window manager service is also notified to unblock projection when
     * no attached view (to the window) displays sensitive content.
     *
     * <ol>
     *   <li>It should only notify service to block projection when first sensitive view is
     *   attached to the window.
     *   <li>It should only notify service to unblock projection when all sensitive view are
     *   removed from the window.
     * </ol>
     */
    void notifySensitiveContentAppProtection(boolean showSensitiveContent) {
        try {
            // The window would be blocked during screen share if it shows sensitive content.
            mSensitiveContentProtectionService.setSensitiveContentProtection(
                    getWindowToken(), mContext.getPackageName(), showSensitiveContent);
        } catch (RemoteException ex) {
            Log.e(TAG, "Unable to protect sensitive content during screen share", ex);
        }
    }
    private void notifyContentCaptureEvents() {
        if (!isContentCaptureEnabled()) {
            if (DEBUG_CONTENT_CAPTURE) {