Merge cherrypicks of ['googleplex-android-review.googlesource.com/27140479', 'googleplex-android-review.googlesource.com/27053555', 'googleplex-android-review.googlesource.com/27250425', 'googleplex-android-review.googlesource.com/27094197', 'googleplex-android-review.googlesource.com/27431144', 'googleplex-android-review.googlesource.com/27263999', 'googleplex-android-review.googlesource.com/27801400'] into 24Q2-release.

Change-Id: Ibeca3b997ee82d1d30cd8872a3ff99b405c8a93d
diff --git a/core/java/android/app/AppOpInfo.java b/core/java/android/app/AppOpInfo.java
index 5268ec4..a0f0cca 100644
--- a/core/java/android/app/AppOpInfo.java
+++ b/core/java/android/app/AppOpInfo.java
@@ -88,7 +88,7 @@
 
     /**
      * This specifies whether each option is only allowed to be read
-     * by apps with manage appops permission.
+     * by apps with privileged appops permission.
      */
     public final boolean restrictRead;
 
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 2afc78c..62f9b59 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -3268,7 +3268,7 @@
     }
 
     /**
-     * Retrieve whether the op can be read by apps with manage appops permission.
+     * Retrieve whether the op can be read by apps with privileged appops permission.
      * @hide
      */
     public static boolean opRestrictsRead(int op) {
diff --git a/core/tests/coretests/src/android/util/BinaryXmlTest.java b/core/tests/coretests/src/android/util/BinaryXmlTest.java
index 025e831..da29828 100644
--- a/core/tests/coretests/src/android/util/BinaryXmlTest.java
+++ b/core/tests/coretests/src/android/util/BinaryXmlTest.java
@@ -24,6 +24,8 @@
 import static android.util.XmlTest.doVerifyWrite;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 import android.os.PersistableBundle;
@@ -41,12 +43,15 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 
 @RunWith(AndroidJUnit4.class)
 public class BinaryXmlTest {
+    private static final int MAX_UNSIGNED_SHORT = 65_535;
+
     /**
      * Verify that we can write and read large numbers of interned
      * {@link String} values.
@@ -170,4 +175,49 @@
             }
         }
     }
+
+    @Test
+    public void testAttributeBytes_BinaryDataOverflow() throws Exception {
+        final TypedXmlSerializer out = Xml.newBinarySerializer();
+        final ByteArrayOutputStream os = new ByteArrayOutputStream();
+        out.setOutput(os, StandardCharsets.UTF_8.name());
+
+        final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT + 1];
+        assertThrows(IOException.class,
+                () -> out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex",
+                        testBytes));
+
+        assertThrows(IOException.class,
+                () -> out.attributeBytesBase64(/* namespace */ null, /* name */
+                        "attributeBytesBase64", testBytes));
+    }
+
+    @Test
+    public void testAttributeBytesHex_MaximumBinaryData() throws Exception {
+        final TypedXmlSerializer out = Xml.newBinarySerializer();
+        final ByteArrayOutputStream os = new ByteArrayOutputStream();
+        out.setOutput(os, StandardCharsets.UTF_8.name());
+
+        final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT];
+        try {
+            out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex", testBytes);
+        } catch (Exception e) {
+            fail("testAttributeBytesHex fails with exception: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testAttributeBytesBase64_MaximumBinaryData() throws Exception {
+        final TypedXmlSerializer out = Xml.newBinarySerializer();
+        final ByteArrayOutputStream os = new ByteArrayOutputStream();
+        out.setOutput(os, StandardCharsets.UTF_8.name());
+
+        final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT];
+        try {
+            out.attributeBytesBase64(/* namespace */ null, /* name */ "attributeBytesBase64",
+                    testBytes);
+        } catch (Exception e) {
+            fail("testAttributeBytesBase64 fails with exception: " + e.toString());
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index 2077d73..ba45d17 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.globalactions.GlobalActionsDialogLite
+import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.qs.dagger.QSFlagsModule.PM_LITE_ENABLED
 import com.android.systemui.qs.footer.data.model.UserSwitcherStatusModel
@@ -109,6 +110,7 @@
         private val falsingManager: FalsingManager,
         private val footerActionsInteractor: FooterActionsInteractor,
         private val globalActionsDialogLiteProvider: Provider<GlobalActionsDialogLite>,
+        private val activityStarter: ActivityStarter,
         @Named(PM_LITE_ENABLED) private val showPowerButton: Boolean,
     ) {
         /** Create a [FooterActionsViewModel] bound to the lifecycle of [lifecycleOwner]. */
@@ -134,6 +136,7 @@
                 footerActionsInteractor,
                 falsingManager,
                 globalActionsDialogLite,
+                activityStarter,
                 showPowerButton,
             )
         }
@@ -145,6 +148,7 @@
     footerActionsInteractor: FooterActionsInteractor,
     falsingManager: FalsingManager,
     globalActionsDialogLite: GlobalActionsDialogLite,
+    activityStarter: ActivityStarter,
     showPowerButton: Boolean,
 ): FooterActionsViewModel {
     suspend fun observeDeviceMonitoringDialogRequests(quickSettingsContext: Context) {
@@ -169,7 +173,14 @@
             return
         }
 
-        footerActionsInteractor.showForegroundServicesDialog(expandable)
+        activityStarter.dismissKeyguardThenExecute(
+            {
+                footerActionsInteractor.showForegroundServicesDialog(expandable)
+                false /* if the dismiss should be deferred */
+            },
+            null /* cancelAction */,
+            true /* afterKeyguardGone */
+        )
     }
 
     fun onUserSwitcherClicked(expandable: Expandable) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt
index 23d657d..89bb16c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt
@@ -27,5 +27,53 @@
 val Kosmos.qsEventLogger: QsEventLoggerFake by
     Kosmos.Fixture { QsEventLoggerFake(uiEventLoggerFake, instanceIdSequenceFake) }
 
-var Kosmos.newQSTileFactory by Kosmos.Fixture<NewQSTileFactory>()
-var Kosmos.qsTileFactory by Kosmos.Fixture<QSFactory>()
+var Kosmos.qsTileFactory by Fixture<QSFactory>()
+
+val Kosmos.fgsManagerController by Fixture { FakeFgsManagerController() }
+
+val Kosmos.footerActionsController by Fixture {
+    FooterActionsController(
+        fgsManagerController = fgsManagerController,
+    )
+}
+
+val Kosmos.qsSecurityFooterUtils by Fixture {
+    QSSecurityFooterUtils(
+        applicationContext,
+        devicePolicyManager,
+        userTracker,
+        fakeExecutorHandler,
+        activityStarter,
+        securityController,
+        looper,
+        dialogTransitionAnimator,
+    )
+}
+
+val Kosmos.footerActionsInteractor by Fixture {
+    FooterActionsInteractorImpl(
+        activityStarter = activityStarter,
+        metricsLogger = metricsLogger,
+        uiEventLogger = uiEventLogger,
+        deviceProvisionedController = deviceProvisionedController,
+        qsSecurityFooterUtils = qsSecurityFooterUtils,
+        fgsManagerController = fgsManagerController,
+        userSwitcherInteractor = userSwitcherInteractor,
+        securityRepository = securityRepository,
+        foregroundServicesRepository = foregroundServicesRepository,
+        userSwitcherRepository = userSwitcherRepository,
+        broadcastDispatcher = broadcastDispatcher,
+        bgDispatcher = testDispatcher,
+    )
+}
+
+val Kosmos.footerActionsViewModelFactory by Fixture {
+    FooterActionsViewModel.Factory(
+        context = applicationContext,
+        falsingManager = falsingManager,
+        footerActionsInteractor = footerActionsInteractor,
+        globalActionsDialogLiteProvider = { mock() },
+        activityStarter,
+        showPowerButton = true,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
index cddb007..cde5d4e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
@@ -68,6 +68,7 @@
     private val testableLooper: TestableLooper,
     private val scheduler: TestCoroutineScheduler,
 ) {
+    private val mockActivityStarter: ActivityStarter = mock<ActivityStarter>()
     /** Enable or disable the user switcher in the settings. */
     fun setUserSwitcherEnabled(settings: GlobalSettings, enabled: Boolean) {
         settings.putBool(Settings.Global.USER_SWITCHER_ENABLED, enabled)
@@ -90,13 +91,14 @@
             footerActionsInteractor,
             falsingManager,
             globalActionsDialogLite,
+            mockActivityStarter,
             showPowerButton,
         )
     }
 
     /** Create a [FooterActionsInteractor] to be used in tests. */
     fun footerActionsInteractor(
-        activityStarter: ActivityStarter = mock(),
+        activityStarter: ActivityStarter = mockActivityStarter,
         metricsLogger: MetricsLogger = FakeMetricsLogger(),
         uiEventLogger: UiEventLogger = UiEventLoggerFake(),
         deviceProvisionedController: DeviceProvisionedController = mock(),
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index fb62785..3908746 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1561,19 +1561,29 @@
     private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops,
             String persistentDeviceId) {
         ArrayList<AppOpsManager.OpEntry> resOps = null;
+        boolean shouldReturnRestrictedAppOps = mContext.checkPermission(
+                Manifest.permission.GET_APP_OPS_STATS,
+                Binder.getCallingPid(), Binder.getCallingUid())
+                == PackageManager.PERMISSION_GRANTED;
         if (ops == null) {
             resOps = new ArrayList<>();
-            for (int j=0; j<pkgOps.size(); j++) {
+            for (int j = 0; j < pkgOps.size(); j++) {
                 Op curOp = pkgOps.valueAt(j);
+                if (opRestrictsRead(curOp.op) && !shouldReturnRestrictedAppOps) {
+                    continue;
+                }
                 resOps.add(getOpEntryForResult(curOp, persistentDeviceId));
             }
         } else {
-            for (int j=0; j<ops.length; j++) {
+            for (int j = 0; j < ops.length; j++) {
                 Op curOp = pkgOps.get(ops[j]);
                 if (curOp != null) {
                     if (resOps == null) {
                         resOps = new ArrayList<>();
                     }
+                    if (opRestrictsRead(curOp.op) && !shouldReturnRestrictedAppOps) {
+                        continue;
+                    }
                     resOps.add(getOpEntryForResult(curOp, persistentDeviceId));
                 }
             }
@@ -4226,10 +4236,21 @@
 
     private void verifyIncomingOp(int op) {
         if (op >= 0 && op < AppOpsManager._NUM_OP) {
-            // Enforce manage appops permission if it's a restricted read op.
+            // Enforce privileged appops permission if it's a restricted read op.
             if (opRestrictsRead(op)) {
-                mContext.enforcePermission(Manifest.permission.MANAGE_APPOPS,
-                        Binder.getCallingPid(), Binder.getCallingUid(), "verifyIncomingOp");
+                if (!(mContext.checkPermission(Manifest.permission.MANAGE_APPOPS,
+                        Binder.getCallingPid(), Binder.getCallingUid())
+                        == PackageManager.PERMISSION_GRANTED || mContext.checkPermission(
+                        Manifest.permission.GET_APP_OPS_STATS,
+                        Binder.getCallingPid(), Binder.getCallingUid())
+                        == PackageManager.PERMISSION_GRANTED || mContext.checkPermission(
+                        Manifest.permission.MANAGE_APP_OPS_MODES,
+                        Binder.getCallingPid(), Binder.getCallingUid())
+                        == PackageManager.PERMISSION_GRANTED)) {
+                    throw new SecurityException("verifyIncomingOp: uid " + Binder.getCallingUid()
+                            + " does not have any of {MANAGE_APPOPS, GET_APP_OPS_STATS, "
+                            + "MANAGE_APP_OPS_MODES}");
+                }
             }
             return;
         }
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 981c4c0..8655b3e 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -99,6 +99,7 @@
 import android.window.SizeConfigurationBuckets;
 import android.window.TransitionInfo;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.AssistUtils;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.protolog.common.ProtoLog;
@@ -108,6 +109,9 @@
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.uri.GrantUri;
 import com.android.server.uri.NeededUriGrants;
+import com.android.server.utils.quota.Categorizer;
+import com.android.server.utils.quota.Category;
+import com.android.server.utils.quota.CountQuotaTracker;
 import com.android.server.vr.VrManagerInternal;
 
 /**
@@ -123,6 +127,13 @@
     private final ActivityTaskSupervisor mTaskSupervisor;
     private final Context mContext;
 
+    // Prevent malicious app abusing the Activity#setPictureInPictureParams API
+    @VisibleForTesting CountQuotaTracker mSetPipAspectRatioQuotaTracker;
+    // Limit to 60 times / minute
+    private static final int SET_PIP_ASPECT_RATIO_LIMIT = 60;
+    // The timeWindowMs here can not be smaller than QuotaTracker#MIN_WINDOW_SIZE_MS
+    private static final long SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS = 60_000;
+
     /** Wrapper around VoiceInteractionServiceManager. */
     private AssistUtils mAssistUtils;
 
@@ -946,6 +957,7 @@
     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
         final long origId = Binder.clearCallingIdentity();
         try {
+            ensureSetPipAspectRatioQuotaTracker();
             synchronized (mGlobalLock) {
                 final ActivityRecord r = ensureValidPictureInPictureActivityParams(
                         "enterPictureInPictureMode", token, params);
@@ -960,6 +972,7 @@
     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
         final long origId = Binder.clearCallingIdentity();
         try {
+            ensureSetPipAspectRatioQuotaTracker();
             synchronized (mGlobalLock) {
                 final ActivityRecord r = ensureValidPictureInPictureActivityParams(
                         "setPictureInPictureParams", token, params);
@@ -1012,6 +1025,19 @@
     }
 
     /**
+     * Initialize the {@link #mSetPipAspectRatioQuotaTracker} if applicable, which should happen
+     * out of {@link #mGlobalLock} to avoid deadlock (AM lock is used in QuotaTrack ctor).
+     */
+    private void ensureSetPipAspectRatioQuotaTracker() {
+        if (mSetPipAspectRatioQuotaTracker == null) {
+            mSetPipAspectRatioQuotaTracker = new CountQuotaTracker(mContext,
+                    Categorizer.SINGLE_CATEGORIZER);
+            mSetPipAspectRatioQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY,
+                    SET_PIP_ASPECT_RATIO_LIMIT, SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS);
+        }
+    }
+
+    /**
      * Checks the state of the system and the activity associated with the given {@param token} to
      * verify that picture-in-picture is supported for that activity.
      *
@@ -1035,6 +1061,19 @@
                     + ": Current activity does not support picture-in-picture.");
         }
 
+        // Rate limit how frequent an app can request aspect ratio change via
+        // Activity#setPictureInPictureParams
+        final int userId = UserHandle.getCallingUserId();
+        if (r.pictureInPictureArgs.hasSetAspectRatio()
+                && params.hasSetAspectRatio()
+                && !r.pictureInPictureArgs.getAspectRatio().equals(
+                params.getAspectRatio())
+                && !mSetPipAspectRatioQuotaTracker.noteEvent(
+                userId, r.packageName, "setPipAspectRatio")) {
+            throw new IllegalStateException(caller
+                    + ": Too many PiP aspect ratio change requests from " + r.packageName);
+        }
+
         final float minAspectRatio = mContext.getResources().getFloat(
                 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
         final float maxAspectRatio = mContext.getResources().getFloat(
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 18ac0e7..852a145 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3065,12 +3065,13 @@
     }
 
     void setForceHideNonSystemOverlayWindowIfNeeded(boolean forceHide) {
+        final int baseType = getBaseType();
         if (mSession.mCanAddInternalSystemWindow
-                || (!isSystemAlertWindowType(mAttrs.type) && mAttrs.type != TYPE_TOAST)) {
+                || (!isSystemAlertWindowType(baseType) && baseType != TYPE_TOAST)) {
             return;
         }
 
-        if (mAttrs.type == TYPE_APPLICATION_OVERLAY && mAttrs.isSystemApplicationOverlay()
+        if (baseType == TYPE_APPLICATION_OVERLAY && mAttrs.isSystemApplicationOverlay()
                 && mSession.mCanCreateSystemApplicationOverlay) {
             return;
         }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
index 42ac998..ad50116 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
@@ -357,8 +357,7 @@
 
         @Override
         boolean shouldWrite() {
-            return (mDeviceOwner != null) || (mSystemUpdatePolicy != null)
-                    || (mSystemUpdateInfo != null);
+            return true;
         }
 
         @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 03b695d..2594987 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1235,6 +1235,12 @@
         assertNotNull(o.mInfo);
         assertNotNull(o.mInfo.pictureInPictureParams);
 
+        // Bypass the quota check, which causes NPE in current test setup.
+        if (mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker != null) {
+            mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker
+                    .setEnabled(false);
+        }
+
         final PictureInPictureParams p2 = new PictureInPictureParams.Builder()
                 .setAspectRatio(new Rational(3, 4)).build();
         mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2);
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 2ff21ad..93809bb 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -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.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 @@
     }
 
     /**
-     * @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();
 
diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp
index a16a7ea..125a825 100644
--- a/tests/UsbManagerTests/Android.bp
+++ b/tests/UsbManagerTests/Android.bp
@@ -42,6 +42,9 @@
         "libmultiplejvmtiagentsinterferenceagent",
         "libstaticjvmtiagent",
     ],
+    libs: [
+        "android.test.mock",
+    ],
     certificate: "platform",
     platform_apis: true,
     test_suites: ["device-tests"],
diff --git a/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java b/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java
index 4780d8a..87b26a6 100644
--- a/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java
+++ b/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java
@@ -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.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 @@
 public class UsbProfileGroupSettingsManagerTest {
 
     private static final String TEST_PACKAGE_NAME = "testPkg";
+
     @Mock
     private Context mContext;
     @Mock
@@ -85,43 +92,78 @@
     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);
-
-        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(mContext.getPackageManager()).thenReturn(mPackageManager);
-        when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
-        when(mContext.getResources()).thenReturn(Mockito.mock(Resources.class));
-        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);
-
         mStaticMockSession = ExtendedMockito.mockitoSession()
                 .mockStatic(Flags.class)
                 .strictness(Strictness.WARN)
                 .startMocking();
 
-        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(mUsbSettingsManager.getSettingsForUser(anyInt())).thenReturn(mUsbUserSettingsManager);
         when(mUserManager.getEnabledProfiles(anyInt()))
                 .thenReturn(List.of(Mockito.mock(UserInfo.class)));
-        when(mUsbSettingsManager.getSettingsForUser(anyInt())).thenReturn(mUsbUserSettingsManager);
+
+        mContentResolver = new MockContentResolver();
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        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);
+
+        mUsbProfileGroupSettingsManager = new UsbProfileGroupSettingsManager(
+                mContext, mUserHandle, mUsbSettingsManager, mUsbHandlerManager);
+
+        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.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 @@
     }
 
     @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);
+                new String[] { android.Manifest.permission.MANAGE_USB },
+                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);
 
-    @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);
+        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);
+
         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));
+    }
 }