Merge "Append 'Seconds' to timeOfClock and timeOfEphemeris" into tm-dev
diff --git a/core/api/current.txt b/core/api/current.txt
index 00d7d80..698c1ce 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -10329,7 +10329,6 @@
     field public static final String ACTION_VIEW_LOCUS = "android.intent.action.VIEW_LOCUS";
     field @RequiresPermission(android.Manifest.permission.START_VIEW_PERMISSION_USAGE) public static final String ACTION_VIEW_PERMISSION_USAGE = "android.intent.action.VIEW_PERMISSION_USAGE";
     field @RequiresPermission(android.Manifest.permission.START_VIEW_PERMISSION_USAGE) public static final String ACTION_VIEW_PERMISSION_USAGE_FOR_PERIOD = "android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD";
-    field @RequiresPermission("android.permission.MANAGE_SENSOR_PRIVACY") public static final String ACTION_VIEW_SAFETY_HUB = "android.intent.action.VIEW_SAFETY_HUB";
     field public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
     field @Deprecated public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
     field public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 213797e..76cac5f 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2823,11 +2823,14 @@
 
   public final class VirtualDeviceParams implements android.os.Parcelable {
     method public int describeContents();
-    method @Nullable public java.util.Set<android.content.ComponentName> getAllowedActivities();
-    method @Nullable public java.util.Set<android.content.ComponentName> getBlockedActivities();
+    method @NonNull public java.util.Set<android.content.ComponentName> getAllowedActivities();
+    method @NonNull public java.util.Set<android.content.ComponentName> getBlockedActivities();
+    method public int getDefaultActivityPolicy();
     method public int getLockState();
     method @NonNull public java.util.Set<android.os.UserHandle> getUsersWithMatchingAccounts();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int ACTIVITY_POLICY_DEFAULT_ALLOWED = 0; // 0x0
+    field public static final int ACTIVITY_POLICY_DEFAULT_BLOCKED = 1; // 0x1
     field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.VirtualDeviceParams> CREATOR;
     field public static final int LOCK_STATE_ALWAYS_UNLOCKED = 1; // 0x1
     field public static final int LOCK_STATE_DEFAULT = 0; // 0x0
@@ -2836,8 +2839,8 @@
   public static final class VirtualDeviceParams.Builder {
     ctor public VirtualDeviceParams.Builder();
     method @NonNull public android.companion.virtual.VirtualDeviceParams build();
-    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAllowedActivities(@Nullable java.util.Set<android.content.ComponentName>);
-    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@Nullable java.util.Set<android.content.ComponentName>);
+    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAllowedActivities(@NonNull java.util.Set<android.content.ComponentName>);
+    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@NonNull java.util.Set<android.content.ComponentName>);
     method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int);
     method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setUsersWithMatchingAccounts(@NonNull java.util.Set<android.os.UserHandle>);
   }
@@ -3035,6 +3038,7 @@
     field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
     field public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED";
     field @RequiresPermission(android.Manifest.permission.START_VIEW_APP_FEATURES) public static final String ACTION_VIEW_APP_FEATURES = "android.intent.action.VIEW_APP_FEATURES";
+    field @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public static final String ACTION_VIEW_SAFETY_CENTER_QS = "android.intent.action.VIEW_SAFETY_CENTER_QS";
     field public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
     field public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS";
     field public static final String EXTRA_CALLING_PACKAGE = "android.intent.extra.CALLING_PACKAGE";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index b752c4d..22637ca 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1073,7 +1073,7 @@
     field public static final int DIALOG = 3; // 0x3
     field public static final int OTHER = 5; // 0x5
     field public static final int QS_TILE = 1; // 0x1
-    field public static final int SAFETY_HUB = 6; // 0x6
+    field public static final int SAFETY_CENTER = 6; // 0x6
     field public static final int SETTINGS = 2; // 0x2
     field public static final int SHELL = 4; // 0x4
   }
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index 45d0ad5..41b1a1f 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -20,9 +20,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.os.Parcel;
@@ -64,20 +62,43 @@
      */
     public static final int LOCK_STATE_ALWAYS_UNLOCKED = 1;
 
+    /** @hide */
+    @IntDef(prefix = "ACTIVITY_POLICY_",
+            value = {ACTIVITY_POLICY_DEFAULT_ALLOWED, ACTIVITY_POLICY_DEFAULT_BLOCKED})
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+    public @interface ActivityPolicy {}
+
+    /**
+     * Indicates that activities are allowed by default on this virtual device, unless they are
+     * explicitly blocked by {@link Builder#setBlockedActivities}.
+     */
+    public static final int ACTIVITY_POLICY_DEFAULT_ALLOWED = 0;
+
+    /**
+     * Indicates that activities are blocked by default on this virtual device, unless they are
+     * allowed by {@link Builder#setAllowedActivities}.
+     */
+    public static final int ACTIVITY_POLICY_DEFAULT_BLOCKED = 1;
+
     private final int mLockState;
     private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
-    @Nullable private final ArraySet<ComponentName> mAllowedActivities;
-    @Nullable private final ArraySet<ComponentName> mBlockedActivities;
+    @NonNull private final ArraySet<ComponentName> mAllowedActivities;
+    @NonNull private final ArraySet<ComponentName> mBlockedActivities;
+    @ActivityPolicy
+    private final int mDefaultActivityPolicy;
 
     private VirtualDeviceParams(
             @LockState int lockState,
             @NonNull Set<UserHandle> usersWithMatchingAccounts,
-            @Nullable Set<ComponentName> allowedActivities,
-            @Nullable Set<ComponentName> blockedActivities) {
+            @NonNull Set<ComponentName> allowedActivities,
+            @NonNull Set<ComponentName> blockedActivities,
+            @ActivityPolicy int defaultActivityPolicy) {
         mLockState = lockState;
         mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts);
         mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities);
         mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities);
+        mDefaultActivityPolicy = defaultActivityPolicy;
     }
 
     @SuppressWarnings("unchecked")
@@ -86,6 +107,7 @@
         mUsersWithMatchingAccounts = (ArraySet<UserHandle>) parcel.readArraySet(null);
         mAllowedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null);
         mBlockedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null);
+        mDefaultActivityPolicy = parcel.readInt();
     }
 
     /**
@@ -113,12 +135,10 @@
      *
      * @see Builder#setAllowedActivities(Set)
      */
-    // Null and empty have different semantics - Null allows all activities to be streamed
-    @SuppressLint("NullableCollection")
-    @Nullable
+    @NonNull
     public Set<ComponentName> getAllowedActivities() {
         if (mAllowedActivities == null) {
-            return null;
+            return Collections.emptySet();
         }
         return Collections.unmodifiableSet(mAllowedActivities);
     }
@@ -129,16 +149,27 @@
      *
      * @see Builder#setBlockedActivities(Set)
      */
-    // Allowing null to enforce that at most one of allowed / blocked activities can be non-null
-    @SuppressLint("NullableCollection")
-    @Nullable
+    @NonNull
     public Set<ComponentName> getBlockedActivities() {
         if (mBlockedActivities == null) {
-            return null;
+            return Collections.emptySet();
         }
         return Collections.unmodifiableSet(mBlockedActivities);
     }
 
+    /**
+     * Returns {@link #ACTIVITY_POLICY_DEFAULT_ALLOWED} if activities are allowed to launch on this
+     * virtual device by default, or {@link #ACTIVITY_POLICY_DEFAULT_BLOCKED} if activities must be
+     * allowed by {@link Builder#setAllowedActivities} to launch here.
+     *
+     * @see Builder#setBlockedActivities
+     * @see Builder#setAllowedActivities
+     */
+    @ActivityPolicy
+    public int getDefaultActivityPolicy() {
+        return mDefaultActivityPolicy;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -150,6 +181,7 @@
         dest.writeArraySet(mUsersWithMatchingAccounts);
         dest.writeArraySet(mAllowedActivities);
         dest.writeArraySet(mBlockedActivities);
+        dest.writeInt(mDefaultActivityPolicy);
     }
 
     @Override
@@ -164,12 +196,15 @@
         return mLockState == that.mLockState
                 && mUsersWithMatchingAccounts.equals(that.mUsersWithMatchingAccounts)
                 && Objects.equals(mAllowedActivities, that.mAllowedActivities)
-                && Objects.equals(mBlockedActivities, that.mBlockedActivities);
+                && Objects.equals(mBlockedActivities, that.mBlockedActivities)
+                && mDefaultActivityPolicy == that.mDefaultActivityPolicy;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mLockState, mUsersWithMatchingAccounts);
+        return Objects.hash(
+                mLockState, mUsersWithMatchingAccounts, mAllowedActivities, mBlockedActivities,
+                mDefaultActivityPolicy);
     }
 
     @Override
@@ -180,6 +215,7 @@
                 + " mUsersWithMatchingAccounts=" + mUsersWithMatchingAccounts
                 + " mAllowedActivities=" + mAllowedActivities
                 + " mBlockedActivities=" + mBlockedActivities
+                + " mDefaultActivityPolicy=" + mDefaultActivityPolicy
                 + ")";
     }
 
@@ -202,8 +238,11 @@
 
         private @LockState int mLockState = LOCK_STATE_DEFAULT;
         private Set<UserHandle> mUsersWithMatchingAccounts;
-        @Nullable private Set<ComponentName> mBlockedActivities;
-        @Nullable private Set<ComponentName> mAllowedActivities;
+        @NonNull private Set<ComponentName> mBlockedActivities = Collections.emptySet();
+        @NonNull private Set<ComponentName> mAllowedActivities = Collections.emptySet();
+        @ActivityPolicy
+        private int mDefaultActivityPolicy = ACTIVITY_POLICY_DEFAULT_ALLOWED;
+        private boolean mDefaultActivityPolicyConfigured = false;
 
         /**
          * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY}
@@ -248,53 +287,53 @@
         }
 
         /**
-         * Sets the activities allowed to be launched in the virtual device. If
-         * {@code allowedActivities} is non-null, all activities other than the ones in the set will
-         * be blocked from launching.
+         * Sets the activities allowed to be launched in the virtual device. Calling this method
+         * will cause {@link #getDefaultActivityPolicy()} to be
+         * {@link #ACTIVITY_POLICY_DEFAULT_BLOCKED}, meaning activities not in
+         * {@code allowedActivities} will be blocked from launching here.
          *
-         * <p>{@code allowedActivities} and the set in {@link #setBlockedActivities(Set)} cannot
-         * both be non-null at the same time.
+         * <p>This method must not be called if {@link #setBlockedActivities(Set)} has been called.
          *
-         * @throws IllegalArgumentException if {@link #setBlockedActivities(Set)} has been set to a
-         *   non-null value.
+         * @throws IllegalArgumentException if {@link #setBlockedActivities(Set)} has been called.
          *
          * @param allowedActivities A set of activity {@link ComponentName} allowed to be launched
          *   in the virtual device.
          */
-        // Null and empty have different semantics - Null allows all activities to be streamed
-        @SuppressLint("NullableCollection")
         @NonNull
-        public Builder setAllowedActivities(@Nullable Set<ComponentName> allowedActivities) {
-            if (mBlockedActivities != null && allowedActivities != null) {
+        public Builder setAllowedActivities(@NonNull Set<ComponentName> allowedActivities) {
+            if (mDefaultActivityPolicyConfigured
+                    && mDefaultActivityPolicy != ACTIVITY_POLICY_DEFAULT_BLOCKED) {
                 throw new IllegalArgumentException(
                         "Allowed activities and Blocked activities cannot both be set.");
             }
+            mDefaultActivityPolicy = ACTIVITY_POLICY_DEFAULT_BLOCKED;
+            mDefaultActivityPolicyConfigured = true;
             mAllowedActivities = allowedActivities;
             return this;
         }
 
         /**
-         * Sets the activities blocked from launching in the virtual device. If the {@code
-         * blockedActivities} is non-null, activities in the set are blocked from launching in the
-         * virtual device.
+         * Sets the activities blocked from launching in the virtual device. Calling this method
+         * will cause {@link #getDefaultActivityPolicy()} to be
+         * {@link #ACTIVITY_POLICY_DEFAULT_ALLOWED}, meaning activities are allowed to launch here
+         * unless they are in {@code blockedActivities}.
          *
-         * {@code blockedActivities} and the set in {@link #setAllowedActivities(Set)} cannot both
-         * be non-null at the same time.
+         * <p>This method must not be called if {@link #setAllowedActivities(Set)} has been called.
          *
-         * @throws IllegalArgumentException if {@link #setAllowedActivities(Set)} has been set to a
-         *   non-null value.
+         * @throws IllegalArgumentException if {@link #setAllowedActivities(Set)} has been called.
          *
          * @param blockedActivities A set of {@link ComponentName} to be blocked launching from
          *   virtual device.
          */
-        // Allowing null to enforce that at most one of allowed / blocked activities can be non-null
-        @SuppressLint("NullableCollection")
         @NonNull
-        public Builder setBlockedActivities(@Nullable Set<ComponentName> blockedActivities) {
-            if (mAllowedActivities != null && blockedActivities != null) {
+        public Builder setBlockedActivities(@NonNull Set<ComponentName> blockedActivities) {
+            if (mDefaultActivityPolicyConfigured
+                    && mDefaultActivityPolicy != ACTIVITY_POLICY_DEFAULT_ALLOWED) {
                 throw new IllegalArgumentException(
                         "Allowed activities and Blocked activities cannot both be set.");
             }
+            mDefaultActivityPolicy = ACTIVITY_POLICY_DEFAULT_ALLOWED;
+            mDefaultActivityPolicyConfigured = true;
             mBlockedActivities = blockedActivities;
             return this;
         }
@@ -307,13 +346,12 @@
             if (mUsersWithMatchingAccounts == null) {
                 mUsersWithMatchingAccounts = Collections.emptySet();
             }
-            if (mAllowedActivities != null && mBlockedActivities != null) {
-                // Should never reach here because the setters block this as well.
-                throw new IllegalStateException(
-                        "Allowed activities and Blocked activities cannot both be set.");
-            }
-            return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts,
-                    mAllowedActivities, mBlockedActivities);
+            return new VirtualDeviceParams(
+                    mLockState,
+                    mUsersWithMatchingAccounts,
+                    mAllowedActivities,
+                    mBlockedActivities,
+                    mDefaultActivityPolicy);
         }
     }
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0aa25ef..478befd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2054,7 +2054,7 @@
             "android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD";
 
     /**
-     * Activity action: Launch the Safety Hub UI.
+     * Activity action: Launch the Safety Center Quick Settings UI.
      *
      * <p>
      * Input: Nothing.
@@ -2062,11 +2062,14 @@
      * <p>
      * Output: Nothing.
      * </p>
+     *
+     * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
-    public static final String ACTION_VIEW_SAFETY_HUB =
-            "android.intent.action.VIEW_SAFETY_HUB";
+    public static final String ACTION_VIEW_SAFETY_CENTER_QS =
+            "android.intent.action.VIEW_SAFETY_CENTER_QS";
 
     /**
      * Activity action: Launch UI to manage a default app.
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index a3cc01c..0460e58 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -136,9 +136,9 @@
         public static final int OTHER = SensorPrivacyToggleSourceProto.OTHER;
 
         /**
-         * Constant for SAFETY_HUB.
+         * Constant for SAFETY_CENTER.
          */
-        public static final int SAFETY_HUB = SensorPrivacyToggleSourceProto.SAFETY_HUB;
+        public static final int SAFETY_CENTER = SensorPrivacyToggleSourceProto.SAFETY_CENTER;
 
         /**
          * Source for toggling sensors
@@ -151,7 +151,7 @@
                 DIALOG,
                 SHELL,
                 OTHER,
-                SAFETY_HUB
+                SAFETY_CENTER
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface Source {}
@@ -652,7 +652,7 @@
         String packageName = mContext.getOpPackageName();
         if (Objects.equals(packageName,
                 mContext.getPackageManager().getPermissionControllerPackageName())) {
-            return Sources.SAFETY_HUB;
+            return Sources.SAFETY_CENTER;
         }
         return Sources.OTHER;
     }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 0956418..68025a8 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -62,6 +62,7 @@
 
 namespace android {
 
+using gui::CaptureArgs;
 using gui::FocusRequest;
 
 static void doThrowNPE(JNIEnv* env) {
diff --git a/core/proto/android/hardware/sensorprivacy.proto b/core/proto/android/hardware/sensorprivacy.proto
index 97870a1..9359528 100644
--- a/core/proto/android/hardware/sensorprivacy.proto
+++ b/core/proto/android/hardware/sensorprivacy.proto
@@ -128,7 +128,7 @@
         DIALOG = 3;
         SHELL = 4;
         OTHER = 5;
-        SAFETY_HUB = 6;
+        SAFETY_CENTER = 6;
     }
 
     // Source for which sensor privacy was toggled.
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 7b85050..fab06c2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -550,13 +550,13 @@
 
         // Album art
         val notif: Notification = sbn.notification
-        var artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ART)
+        var artworkBitmap = metadata?.let { loadBitmapFromUri(it) }
+        if (artworkBitmap == null) {
+            artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ART)
+        }
         if (artworkBitmap == null) {
             artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
         }
-        if (artworkBitmap == null && metadata != null) {
-            artworkBitmap = loadBitmapFromUri(metadata)
-        }
         val artWorkIcon = if (artworkBitmap == null) {
             notif.getLargeIcon()
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 89735c3..5d9361d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -370,6 +370,7 @@
                 PowerExemptionManager.REASON_SYSTEM_UID,
                 PowerExemptionManager.REASON_DEVICE_DEMO_MODE -> UIControl.HIDE_ENTRY
 
+                PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE,
                 PowerExemptionManager.REASON_DEVICE_OWNER,
                 PowerExemptionManager.REASON_PROFILE_OWNER,
                 PowerExemptionManager.REASON_PROC_STATE_PERSISTENT,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt b/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
index 8afb793..95b4b72 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
@@ -118,7 +118,7 @@
             // If the privacy chip is visible, it means there were some indicators
             uiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK)
             if (safetyCenterEnabled) {
-                showSafetyHub()
+                showSafetyCenter()
             } else {
                 privacyDialogController.showDialog(privacyChip.context)
             }
@@ -131,16 +131,16 @@
         updatePrivacyIconSlots()
     }
 
-    private fun showSafetyHub() {
+    private fun showSafetyCenter() {
         backgroundExecutor.execute {
             val usage = ArrayList(permGroupUsage())
             privacyLogger.logUnfilteredPermGroupUsage(usage)
-            val startSafetyHub = Intent(Intent.ACTION_VIEW_SAFETY_HUB)
-            startSafetyHub.putParcelableArrayListExtra(PermissionManager.EXTRA_PERMISSION_USAGES,
+            val startSafetyCenter = Intent(Intent.ACTION_VIEW_SAFETY_CENTER_QS)
+            startSafetyCenter.putParcelableArrayListExtra(PermissionManager.EXTRA_PERMISSION_USAGES,
                 usage)
-            startSafetyHub.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+            startSafetyCenter.flags = Intent.FLAG_ACTIVITY_NEW_TASK
             uiExecutor.execute {
-                activityStarter.startActivity(startSafetyHub, true,
+                activityStarter.startActivity(startSafetyCenter, true,
                     ActivityLaunchAnimator.Controller.fromView(privacyChip))
             }
         }
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index bc1f28d..b991ba8 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -24,6 +24,8 @@
 import android.annotation.Nullable;
 import android.app.compat.CompatChanges;
 import android.companion.virtual.VirtualDeviceManager.ActivityListener;
+import android.companion.virtual.VirtualDeviceParams;
+import android.companion.virtual.VirtualDeviceParams.ActivityPolicy;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
 import android.content.ComponentName;
@@ -77,7 +79,9 @@
     @Nullable
     private final ArraySet<ComponentName> mBlockedActivities;
     private final Object mGenericWindowPolicyControllerLock = new Object();
-    private Consumer<ActivityInfo> mActivityBlockedCallback;
+    @ActivityPolicy
+    private final int mDefaultActivityPolicy;
+    private final Consumer<ActivityInfo> mActivityBlockedCallback;
 
     @NonNull
     @GuardedBy("mGenericWindowPolicyControllerLock")
@@ -95,18 +99,30 @@
      * @param windowFlags The window flags that this controller is interested in.
      * @param systemWindowFlags The system window flags that this controller is interested in.
      * @param allowedUsers The set of users that are allowed to stream in this display.
+     * @param allowedActivities The set of activities explicitly allowed to stream on this device.
+     *   Used only if the {@code activityPolicy} is
+     *   {@link VirtualDeviceParams#ACTIVITY_POLICY_DEFAULT_BLOCKED}.
+     * @param blockedActivities The set of activities explicitly blocked from streaming on this
+     *   device. Used only if the {@code activityPolicy} is
+     *   {@link VirtualDeviceParams#ACTIVITY_POLICY_DEFAULT_ALLOWED}
+     * @param defaultActivityPolicy Whether activities are default allowed to be displayed or
+     *   blocked.
      * @param activityListener Activity listener to listen for activity changes. The display ID
      *   is not populated in this callback and is always {@link Display#INVALID_DISPLAY}.
+     * @param activityBlockedCallback Callback that is called when an activity is blocked from
+     *   launching.
      */
     public GenericWindowPolicyController(int windowFlags, int systemWindowFlags,
             @NonNull ArraySet<UserHandle> allowedUsers,
-            @Nullable Set<ComponentName> allowedActivities,
-            @Nullable Set<ComponentName> blockedActivities,
+            @NonNull Set<ComponentName> allowedActivities,
+            @NonNull Set<ComponentName> blockedActivities,
+            @ActivityPolicy int defaultActivityPolicy,
             @NonNull ActivityListener activityListener,
             @NonNull Consumer<ActivityInfo> activityBlockedCallback) {
         mAllowedUsers = allowedUsers;
-        mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities);
-        mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities);
+        mAllowedActivities = new ArraySet<>(allowedActivities);
+        mBlockedActivities = new ArraySet<>(blockedActivities);
+        mDefaultActivityPolicy = defaultActivityPolicy;
         mActivityBlockedCallback = activityBlockedCallback;
         setInterestedWindowFlags(windowFlags, systemWindowFlags);
         mActivityListener = activityListener;
@@ -191,11 +207,13 @@
             Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser);
             return false;
         }
-        if (mBlockedActivities != null && mBlockedActivities.contains(activityComponent)) {
+        if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED
+                && mBlockedActivities.contains(activityComponent)) {
             Slog.d(TAG, "Virtual device blocking launch of " + activityComponent);
             return false;
         }
-        if (mAllowedActivities != null && !mAllowedActivities.contains(activityComponent)) {
+        if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED
+                && !mAllowedActivities.contains(activityComponent)) {
             Slog.d(TAG, activityComponent + " is not in the allowed list.");
             return false;
         }
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index c0a904f..dbb48ae 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -505,6 +505,7 @@
                             getAllowedUserHandles(),
                             mParams.getAllowedActivities(),
                             mParams.getBlockedActivities(),
+                            mParams.getDefaultActivityPolicy(),
                             createListenerAdapter(displayId),
                             activityInfo -> onActivityBlocked(displayId, activityInfo));
             mWindowPolicyControllers.put(displayId, dwpc);
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index 3160272..f0c907d 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.companion.virtual.VirtualDeviceParams;
 import android.companion.virtual.audio.IAudioSessionCallback;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -72,7 +73,8 @@
                 /* allowedUsers= */ new ArraySet<>(),
                 /* allowedActivities= */ new ArraySet<>(),
                 /* blockedActivities= */ new ArraySet<>(),
-                /* activityListener= */null,
+                VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED,
+                /* activityListener= */ null,
                 /* activityBlockedCallback= */ null);
     }