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

Commit 4d9a9ede authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/29613539',...

Merge cherrypicks of ['googleplex-android-review.googlesource.com/29613539', 'googleplex-android-review.googlesource.com/29616258', 'googleplex-android-review.googlesource.com/29677529', 'googleplex-android-review.googlesource.com/29669826', 'googleplex-android-review.googlesource.com/29732966', 'googleplex-android-review.googlesource.com/29733285'] into 24Q4-release.

Change-Id: I68b4db9f996cc0d7a80e6cdbb2ea1f3d6b68337c
parents b95f1565 0a4f6aa9
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -347,7 +347,12 @@ public class QuickStepContract {
        }
        // Disable back gesture on the hub, but not when the shade is showing.
        if ((sysuiStateFlags & SYSUI_STATE_COMMUNAL_HUB_SHOWING) != 0) {
            return (sysuiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE) == 0;
            // Use QS expanded signal as the notification panel is always considered visible
            // expanded when on the lock screen and when opening hub over lock screen. This does
            // mean that back gesture is disabled when opening shade over hub while in portrait
            // mode, since QS is not expanded.
            // TODO(b/370108274): allow back gesture on shade over hub in portrait
            return (sysuiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0;
        }
        if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
            sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN;
+3 −3
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import org.junit.runner.RunWith
@@ -41,9 +41,9 @@ class QuickStepContractTest : SysuiTestCase() {
    }

    @Test
    fun isBackGestureDisabled_hubAndShadeShowing() {
    fun isBackGestureDisabled_hubAndQSExpanded() {
        val sysuiStateFlags =
            SYSUI_STATE_COMMUNAL_HUB_SHOWING and SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
            SYSUI_STATE_COMMUNAL_HUB_SHOWING and SYSUI_STATE_QUICK_SETTINGS_EXPANDED

        // Gestures are enabled because the shade shows over the hub.
        assertThat(
+4 −4
Original line number Diff line number Diff line
@@ -725,7 +725,7 @@ public class BiometricService extends SystemService {
                return -1;
            }

            if (!Utils.isValidAuthenticatorConfig(promptInfo)) {
            if (!Utils.isValidAuthenticatorConfig(getContext(), promptInfo)) {
                throw new SecurityException("Invalid authenticator configuration");
            }

@@ -763,7 +763,7 @@ public class BiometricService extends SystemService {
                    + ", Caller=" + callingUserId
                    + ", Authenticators=" + authenticators);

            if (!Utils.isValidAuthenticatorConfig(authenticators)) {
            if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) {
                throw new SecurityException("Invalid authenticator configuration");
            }

@@ -1038,7 +1038,7 @@ public class BiometricService extends SystemService {
                    + ", Caller=" + callingUserId
                    + ", Authenticators=" + authenticators);

            if (!Utils.isValidAuthenticatorConfig(authenticators)) {
            if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) {
                throw new SecurityException("Invalid authenticator configuration");
            }

@@ -1060,7 +1060,7 @@ public class BiometricService extends SystemService {

            Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators);

            if (!Utils.isValidAuthenticatorConfig(authenticators)) {
            if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) {
                throw new SecurityException("Invalid authenticator configuration");
            }

+20 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.biometrics;

import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
import static android.hardware.biometrics.BiometricManager.Authenticators;
@@ -233,17 +234,18 @@ public class Utils {
     * @param promptInfo
     * @return
     */
    static boolean isValidAuthenticatorConfig(PromptInfo promptInfo) {
    static boolean isValidAuthenticatorConfig(Context context, PromptInfo promptInfo) {
        final int authenticators = promptInfo.getAuthenticators();
        return isValidAuthenticatorConfig(authenticators);
        return isValidAuthenticatorConfig(context, authenticators);
    }

    /**
     * Checks if the authenticator configuration is a valid combination of the public APIs
     * @param authenticators
     * @return
     * Checks if the authenticator configuration is a valid combination of the public APIs.
     *
     * throws {@link SecurityException} if the caller requests for mandatory biometrics without
     * {@link SET_BIOMETRIC_DIALOG_ADVANCED} permission
     */
    static boolean isValidAuthenticatorConfig(int authenticators) {
    static boolean isValidAuthenticatorConfig(Context context, int authenticators) {
        // The caller is not required to set the authenticators. But if they do, check the below.
        if (authenticators == 0) {
            return true;
@@ -251,9 +253,15 @@ public class Utils {

        // Check if any of the non-biometric and non-credential bits are set. If so, this is
        // invalid.
        final int testBits = ~(Authenticators.DEVICE_CREDENTIAL
        final int testBits;
        if (Flags.mandatoryBiometrics()) {
            testBits = ~(Authenticators.DEVICE_CREDENTIAL
                    | Authenticators.BIOMETRIC_MIN_STRENGTH
                    | Authenticators.MANDATORY_BIOMETRICS);
        } else {
            testBits = ~(Authenticators.DEVICE_CREDENTIAL
                    | Authenticators.BIOMETRIC_MIN_STRENGTH);
        }
        if ((authenticators & testBits) != 0) {
            Slog.e(BiometricService.TAG, "Non-biometric, non-credential bits found."
                    + " Authenticators: " + authenticators);
@@ -271,6 +279,9 @@ public class Utils {
        } else if (biometricBits == Authenticators.BIOMETRIC_WEAK) {
            return true;
        } else if (isMandatoryBiometricsRequested(authenticators)) {
            //TODO(b/347123256): Update CTS test
            context.enforceCallingOrSelfPermission(SET_BIOMETRIC_DIALOG_ADVANCED,
                    "Must have SET_BIOMETRIC_DIALOG_ADVANCED permission");
            return true;
        }

+33 −5
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import android.app.AppOpsManager;
import android.app.IProcessObserver;
import android.app.KeyguardManager;
import android.app.compat.CompatChanges;
import android.app.role.RoleManager;
import android.companion.AssociationRequest;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
@@ -94,7 +96,7 @@ import java.util.Objects;

/**
 * Manages MediaProjection sessions.
 *
 * <p>
 * The {@link MediaProjectionManagerService} manages the creation and lifetime of MediaProjections,
 * as well as the capabilities they grant. Any service using MediaProjection tokens as permission
 * grants <b>must</b> validate the token before use by calling {@link
@@ -137,6 +139,7 @@ public final class MediaProjectionManagerService extends SystemService
    private final PackageManager mPackageManager;
    private final WindowManagerInternal mWmInternal;
    private final KeyguardManager mKeyguardManager;
    private final RoleManager mRoleManager;

    private final MediaRouter mMediaRouter;
    private final MediaRouterCallback mMediaRouterCallback;
@@ -173,6 +176,7 @@ public final class MediaProjectionManagerService extends SystemService
        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
        mKeyguardManager.addKeyguardLockedStateListener(
                mContext.getMainExecutor(), this::onKeyguardLockedStateChanged);
        mRoleManager = mContext.getSystemService(RoleManager.class);
        Watchdog.getInstance().addMonitor(this);
    }

@@ -182,6 +186,7 @@ public final class MediaProjectionManagerService extends SystemService
     *   - be one of the bugreport allowlisted packages, or
     *   - hold the OP_PROJECT_MEDIA AppOp.
     */
    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
    private boolean canCaptureKeyguard() {
        if (!android.companion.virtualdevice.flags.Flags.mediaProjectionKeyguardRestrictions()) {
            return true;
@@ -193,14 +198,23 @@ public final class MediaProjectionManagerService extends SystemService
            if (mPackageManager.checkPermission(RECORD_SENSITIVE_CONTENT,
                    mProjectionGrant.packageName)
                    == PackageManager.PERMISSION_GRANTED) {
                Slog.v(TAG,
                        "Allowing keyguard capture for package with RECORD_SENSITIVE_CONTENT "
                                + "permission");
                return true;
            }
            boolean operationActive = mAppOps.isOperationActive(AppOpsManager.OP_PROJECT_MEDIA,
                    mProjectionGrant.uid,
                    mProjectionGrant.packageName);
            if (operationActive) {
            if (AppOpsManager.MODE_ALLOWED == mAppOps.noteOpNoThrow(AppOpsManager.OP_PROJECT_MEDIA,
                    mProjectionGrant.uid, mProjectionGrant.packageName, /* attributionTag= */ null,
                    "recording lockscreen")) {
                // Some tools use media projection by granting the OP_PROJECT_MEDIA app
                // op via a shell command. Those tools can be granted keyguard capture
                Slog.v(TAG,
                        "Allowing keyguard capture for package with OP_PROJECT_MEDIA AppOp ");
                return true;
            }
            if (isProjectionAppHoldingAppStreamingRoleLocked()) {
                Slog.v(TAG,
                        "Allowing keyguard capture for package holding app streaming role.");
                return true;
            }
            return SystemConfig.getInstance().getBugreportWhitelistedPackages()
@@ -699,6 +713,20 @@ public final class MediaProjectionManagerService extends SystemService
        }
    }

    /**
     * Application holding the app streaming role
     * ({@value AssociationRequest#DEVICE_PROFILE_APP_STREAMING}) are allowed to record the
     * lockscreen.
     *
     * @return true if the is held by the recording application.
     */
    @GuardedBy("mLock")
    private boolean isProjectionAppHoldingAppStreamingRoleLocked() {
        return mRoleManager.getRoleHoldersAsUser(AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
                        mContext.getUser())
                .contains(mProjectionGrant.packageName);
    }

    private void dump(final PrintWriter pw) {
        pw.println("MEDIA PROJECTION MANAGER (dumpsys media_projection)");
        synchronized (mLock) {
Loading