Merge "Fix NPE caused by orphaned child sessions"
diff --git a/boot/hiddenapi/hiddenapi-unsupported.txt b/boot/hiddenapi/hiddenapi-unsupported.txt
index 002d42d..522e88f 100644
--- a/boot/hiddenapi/hiddenapi-unsupported.txt
+++ b/boot/hiddenapi/hiddenapi-unsupported.txt
@@ -124,10 +124,8 @@
 Landroid/content/pm/IPackageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageManager$Stub$Proxy;->checkUidPermission(Ljava/lang/String;I)I
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
-Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstallLocation()I
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;I)Landroid/content/pm/ResolveInfo;
-Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String;
 Landroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager;
diff --git a/core/api/current.txt b/core/api/current.txt
index 6f58a38..b40a3e5 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9037,11 +9037,15 @@
 
   public final class BluetoothClass implements android.os.Parcelable {
     method public int describeContents();
+    method public boolean doesClassMatch(int);
     method public int getDeviceClass();
     method public int getMajorDeviceClass();
     method public boolean hasService(int);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothClass> CREATOR;
+    field public static final int PROFILE_A2DP = 1; // 0x1
+    field public static final int PROFILE_HEADSET = 0; // 0x0
+    field public static final int PROFILE_HID = 3; // 0x3
   }
 
   public static class BluetoothClass.Device {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 45fac2e..dd1760c 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2024,6 +2024,13 @@
     method public void onOobData(int, @NonNull android.bluetooth.OobData);
   }
 
+  public final class BluetoothClass implements android.os.Parcelable {
+    field public static final int PROFILE_A2DP_SINK = 6; // 0x6
+    field public static final int PROFILE_NAP = 5; // 0x5
+    field public static final int PROFILE_OPP = 2; // 0x2
+    field public static final int PROFILE_PANU = 4; // 0x4
+  }
+
   public final class BluetoothCsipSetCoordinator implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
     method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<java.lang.Integer> getAllGroupIds(@Nullable android.os.ParcelUuid);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 008a178..c1ab070 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1831,11 +1831,6 @@
     method public int getAudioUsage();
   }
 
-  public static final class VibrationAttributes.Builder {
-    ctor public VibrationAttributes.Builder(@NonNull android.media.AudioAttributes, @NonNull android.os.VibrationEffect);
-    ctor public VibrationAttributes.Builder(@NonNull android.os.VibrationAttributes, @NonNull android.os.VibrationEffect);
-  }
-
   public abstract class VibrationEffect implements android.os.Parcelable {
     method public static android.os.VibrationEffect get(int);
     method public static android.os.VibrationEffect get(int, boolean);
@@ -1852,13 +1847,9 @@
   }
 
   public static final class VibrationEffect.Composed extends android.os.VibrationEffect {
-    method @NonNull public android.os.VibrationEffect.Composed applyEffectStrength(int);
     method public long getDuration();
     method public int getRepeatIndex();
     method @NonNull public java.util.List<android.os.vibrator.VibrationEffectSegment> getSegments();
-    method @NonNull public android.os.VibrationEffect.Composed resolve(int);
-    method @NonNull public android.os.VibrationEffect.Composed scale(float);
-    method public void validate();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Composed> CREATOR;
   }
@@ -2006,72 +1997,47 @@
 package android.os.vibrator {
 
   public final class PrebakedSegment extends android.os.vibrator.VibrationEffectSegment {
-    method @NonNull public android.os.vibrator.PrebakedSegment applyEffectStrength(int);
     method public int describeContents();
     method public long getDuration();
     method public int getEffectId();
     method public int getEffectStrength();
-    method public boolean hasNonZeroAmplitude();
-    method @NonNull public android.os.vibrator.PrebakedSegment resolve(int);
-    method @NonNull public android.os.vibrator.PrebakedSegment scale(float);
     method public boolean shouldFallback();
-    method public void validate();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.PrebakedSegment> CREATOR;
   }
 
   public final class PrimitiveSegment extends android.os.vibrator.VibrationEffectSegment {
-    method @NonNull public android.os.vibrator.PrimitiveSegment applyEffectStrength(int);
     method public int describeContents();
     method public int getDelay();
     method public long getDuration();
     method public int getPrimitiveId();
     method public float getScale();
-    method public boolean hasNonZeroAmplitude();
-    method @NonNull public android.os.vibrator.PrimitiveSegment resolve(int);
-    method @NonNull public android.os.vibrator.PrimitiveSegment scale(float);
-    method public void validate();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.PrimitiveSegment> CREATOR;
   }
 
   public final class RampSegment extends android.os.vibrator.VibrationEffectSegment {
-    method @NonNull public android.os.vibrator.RampSegment applyEffectStrength(int);
     method public int describeContents();
     method public long getDuration();
     method public float getEndAmplitude();
     method public float getEndFrequency();
     method public float getStartAmplitude();
     method public float getStartFrequency();
-    method public boolean hasNonZeroAmplitude();
-    method @NonNull public android.os.vibrator.RampSegment resolve(int);
-    method @NonNull public android.os.vibrator.RampSegment scale(float);
-    method public void validate();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.RampSegment> CREATOR;
   }
 
   public final class StepSegment extends android.os.vibrator.VibrationEffectSegment {
-    method @NonNull public android.os.vibrator.StepSegment applyEffectStrength(int);
     method public int describeContents();
     method public float getAmplitude();
     method public long getDuration();
     method public float getFrequency();
-    method public boolean hasNonZeroAmplitude();
-    method @NonNull public android.os.vibrator.StepSegment resolve(int);
-    method @NonNull public android.os.vibrator.StepSegment scale(float);
-    method public void validate();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.StepSegment> CREATOR;
   }
 
   public abstract class VibrationEffectSegment implements android.os.Parcelable {
-    method @NonNull public abstract <T extends android.os.vibrator.VibrationEffectSegment> T applyEffectStrength(int);
     method public abstract long getDuration();
-    method public abstract boolean hasNonZeroAmplitude();
-    method @NonNull public abstract <T extends android.os.vibrator.VibrationEffectSegment> T resolve(int);
-    method @NonNull public abstract <T extends android.os.vibrator.VibrationEffectSegment> T scale(float);
-    method public abstract void validate();
     field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.VibrationEffectSegment> CREATOR;
   }
 
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 7fe18a0..69525b5 100755
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -327,21 +328,26 @@
         return Arrays.copyOfRange(bytes, 1, bytes.length);
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
     public static final int PROFILE_HEADSET = 0;
-    /** @hide */
-    @UnsupportedAppUsage
+
     public static final int PROFILE_A2DP = 1;
+
     /** @hide */
+    @SystemApi
     public static final int PROFILE_OPP = 2;
-    /** @hide */
+
     public static final int PROFILE_HID = 3;
+
     /** @hide */
+    @SystemApi
     public static final int PROFILE_PANU = 4;
+
     /** @hide */
+    @SystemApi
     public static final int PROFILE_NAP = 5;
+
     /** @hide */
+    @SystemApi
     public static final int PROFILE_A2DP_SINK = 6;
 
     /**
@@ -350,11 +356,9 @@
      * given class bits might support specified profile. It is not accurate for all
      * devices. It tries to err on the side of false positives.
      *
-     * @param profile The profile to be checked
-     * @return True if this device might support specified profile.
-     * @hide
+     * @param profile the profile to be checked
+     * @return whether this device supports specified profile
      */
-    @UnsupportedAppUsage
     public boolean doesClassMatch(int profile) {
         if (profile == PROFILE_A2DP) {
             if (hasService(Service.RENDER)) {
diff --git a/core/java/android/companion/AssociationInfo.java b/core/java/android/companion/AssociationInfo.java
index f70e662..3f02aa2 100644
--- a/core/java/android/companion/AssociationInfo.java
+++ b/core/java/android/companion/AssociationInfo.java
@@ -118,7 +118,7 @@
 
     /** @hide */
     public @Nullable String getDeviceMacAddressAsString() {
-        return mDeviceMacAddress != null ? mDeviceMacAddress.toString() : null;
+        return mDeviceMacAddress != null ? mDeviceMacAddress.toString().toUpperCase() : null;
     }
 
     /**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 516156d..1c82b38 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -69,41 +69,34 @@
     void checkPackageStartable(String packageName, int userId);
     @UnsupportedAppUsage(trackingBug = 171933273)
     boolean isPackageAvailable(String packageName, int userId);
-    @UnsupportedAppUsage
-    PackageInfo getPackageInfo(String packageName, int flags, int userId);
+    PackageInfo getPackageInfo(String packageName, long flags, int userId);
     PackageInfo getPackageInfoVersioned(in VersionedPackage versionedPackage,
-            int flags, int userId);
-    @UnsupportedAppUsage
-    int getPackageUid(String packageName, int flags, int userId);
-    int[] getPackageGids(String packageName, int flags, int userId);
+            long flags, int userId);
+    int getPackageUid(String packageName, long flags, int userId);
+    int[] getPackageGids(String packageName, long flags, int userId);
 
     @UnsupportedAppUsage
     String[] currentToCanonicalPackageNames(in String[] names);
     @UnsupportedAppUsage
     String[] canonicalToCurrentPackageNames(in String[] names);
 
-    @UnsupportedAppUsage
-    ApplicationInfo getApplicationInfo(String packageName, int flags ,int userId);
+    ApplicationInfo getApplicationInfo(String packageName, long flags, int userId);
 
     /**
      * @return the target SDK for the given package name, or -1 if it cannot be retrieved
      */
     int getTargetSdkVersion(String packageName);
 
-    @UnsupportedAppUsage
-    ActivityInfo getActivityInfo(in ComponentName className, int flags, int userId);
+    ActivityInfo getActivityInfo(in ComponentName className, long flags, int userId);
 
     boolean activitySupportsIntent(in ComponentName className, in Intent intent,
             String resolvedType);
 
-    @UnsupportedAppUsage
-    ActivityInfo getReceiverInfo(in ComponentName className, int flags, int userId);
+    ActivityInfo getReceiverInfo(in ComponentName className, long flags, int userId);
 
-    @UnsupportedAppUsage
-    ServiceInfo getServiceInfo(in ComponentName className, int flags, int userId);
+    ServiceInfo getServiceInfo(in ComponentName className, long flags, int userId);
 
-    @UnsupportedAppUsage
-    ProviderInfo getProviderInfo(in ComponentName className, int flags, int userId);
+    ProviderInfo getProviderInfo(in ComponentName className, long flags, int userId);
 
     boolean isProtectedBroadcast(String actionName);
 
@@ -133,33 +126,31 @@
     @UnsupportedAppUsage
     boolean isUidPrivileged(int uid);
 
-    @UnsupportedAppUsage
-    ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId);
+    ResolveInfo resolveIntent(in Intent intent, String resolvedType, long flags, int userId);
 
     ResolveInfo findPersistentPreferredActivity(in Intent intent, int userId);
 
     boolean canForwardTo(in Intent intent, String resolvedType, int sourceUserId, int targetUserId);
 
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     ParceledListSlice queryIntentActivities(in Intent intent,
-            String resolvedType, int flags, int userId);
+            String resolvedType, long flags, int userId);
 
     ParceledListSlice queryIntentActivityOptions(
             in ComponentName caller, in Intent[] specifics,
             in String[] specificTypes, in Intent intent,
-            String resolvedType, int flags, int userId);
+            String resolvedType, long flags, int userId);
 
     ParceledListSlice queryIntentReceivers(in Intent intent,
-            String resolvedType, int flags, int userId);
+            String resolvedType, long flags, int userId);
 
     ResolveInfo resolveService(in Intent intent,
-            String resolvedType, int flags, int userId);
+            String resolvedType, long flags, int userId);
 
     ParceledListSlice queryIntentServices(in Intent intent,
-            String resolvedType, int flags, int userId);
+            String resolvedType, long flags, int userId);
 
     ParceledListSlice queryIntentContentProviders(in Intent intent,
-            String resolvedType, int flags, int userId);
+            String resolvedType, long flags, int userId);
 
     /**
      * This implements getInstalledPackages via a "last returned row"
@@ -167,8 +158,7 @@
      * limit that kicks in when flags are included that bloat up the data
      * returned.
      */
-    @UnsupportedAppUsage
-    ParceledListSlice getInstalledPackages(int flags, in int userId);
+    ParceledListSlice getInstalledPackages(long flags, in int userId);
 
     /**
      * This implements getPackagesHoldingPermissions via a "last returned row"
@@ -177,7 +167,7 @@
      * returned.
      */
     ParceledListSlice getPackagesHoldingPermissions(in String[] permissions,
-            int flags, int userId);
+            long flags, int userId);
 
     /**
      * This implements getInstalledApplications via a "last returned row"
@@ -185,18 +175,17 @@
      * limit that kicks in when flags are included that bloat up the data
      * returned.
      */
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    ParceledListSlice getInstalledApplications(int flags, int userId);
+    ParceledListSlice getInstalledApplications(long flags, int userId);
 
     /**
      * Retrieve all applications that are marked as persistent.
      *
-     * @return A List&lt;applicationInfo> containing one entry for each persistent
+     * @return A List<ApplicationInfo> containing one entry for each persistent
      *         application.
      */
     ParceledListSlice getPersistentApplications(int flags);
 
-    ProviderInfo resolveContentProvider(String name, int flags, int userId);
+    ProviderInfo resolveContentProvider(String name, long flags, int userId);
 
     /**
      * Retrieve sync information for all content providers.
@@ -211,7 +200,7 @@
             inout List<ProviderInfo> outInfo);
 
     ParceledListSlice queryContentProviders(
-            String processName, int uid, int flags, String metaDataKey);
+            String processName, int uid, long flags, String metaDataKey);
 
     @UnsupportedAppUsage
     InstrumentationInfo getInstrumentationInfo(
@@ -690,9 +679,9 @@
 
     int getInstallReason(String packageName, int userId);
 
-    ParceledListSlice getSharedLibraries(in String packageName, int flags, int userId);
+    ParceledListSlice getSharedLibraries(in String packageName, long flags, int userId);
 
-    ParceledListSlice getDeclaredSharedLibraries(in String packageName, int flags, int userId);
+    ParceledListSlice getDeclaredSharedLibraries(in String packageName, long flags, int userId);
 
     boolean canRequestPackageInstalls(String packageName, int userId);
 
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index cc4782a..aa57806 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -10,6 +10,9 @@
       "path": "frameworks/base/services/tests/PackageManagerComponentOverrideTests"
     },
     {
+      "path": "frameworks/base/services/tests/servicestests/src/com/android/server/pm"
+    },
+    {
       "path": "cts/tests/tests/packageinstaller"
     },
     {
diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
index ef124c7..b11b38a 100644
--- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
+++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
@@ -76,7 +76,7 @@
 
     @Nullable
     public static PackageInfo generate(ParsingPackageRead pkg, int[] gids,
-            @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
+            @PackageManager.PackageInfoFlags long flags, long firstInstallTime, long lastUpdateTime,
             Set<String> grantedPermissions, FrameworkPackageUserState state, int userId) {
         return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions,
                 state, userId, null);
@@ -90,7 +90,7 @@
 
     @Nullable
     private static PackageInfo generateWithComponents(ParsingPackageRead pkg, int[] gids,
-            @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
+            @PackageManager.PackageInfoFlags long flags, long firstInstallTime, long lastUpdateTime,
             Set<String> grantedPermissions, FrameworkPackageUserState state, int userId,
             @Nullable ApexInfo apexInfo) {
         ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
@@ -190,7 +190,7 @@
 
     @Nullable
     public static PackageInfo generateWithoutComponents(ParsingPackageRead pkg, int[] gids,
-            @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
+            @PackageManager.PackageInfoFlags long flags, long firstInstallTime, long lastUpdateTime,
             Set<String> grantedPermissions, FrameworkPackageUserState state, int userId,
             @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
         if (!checkUseInstalled(pkg, state, flags)) {
@@ -210,9 +210,9 @@
      */
     @NonNull
     public static PackageInfo generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids,
-            @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
-            Set<String> grantedPermissions, FrameworkPackageUserState state, int userId,
-            @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
+            @PackageManager.PackageInfoFlags long flags, long firstInstallTime,
+            long lastUpdateTime, Set<String> grantedPermissions, FrameworkPackageUserState state,
+            int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
         PackageInfo pi = new PackageInfo();
         pi.packageName = pkg.getPackageName();
         pi.splitNames = pkg.getSplitNames();
@@ -365,7 +365,8 @@
 
     @Nullable
     public static ApplicationInfo generateApplicationInfo(ParsingPackageRead pkg,
-            @PackageManager.ApplicationInfoFlags int flags, FrameworkPackageUserState state, int userId) {
+            @PackageManager.ApplicationInfoFlags long flags, FrameworkPackageUserState state,
+            int userId) {
         if (pkg == null) {
             return null;
         }
@@ -392,8 +393,8 @@
      */
     @NonNull
     public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg,
-            @PackageManager.ApplicationInfoFlags int flags, @NonNull FrameworkPackageUserState state,
-            int userId, boolean assignUserFields) {
+            @PackageManager.ApplicationInfoFlags long flags,
+            @NonNull FrameworkPackageUserState state, int userId, boolean assignUserFields) {
         // Make shallow copy so we can store the metadata/libraries safely
         ApplicationInfo ai = ((ParsingPackageHidden) pkg).toAppInfoWithoutState();
 
@@ -406,7 +407,7 @@
         return ai;
     }
 
-    private static void updateApplicationInfo(ApplicationInfo ai, int flags,
+    private static void updateApplicationInfo(ApplicationInfo ai, long flags,
             FrameworkPackageUserState state) {
         if ((flags & PackageManager.GET_META_DATA) == 0) {
             ai.metaData = null;
@@ -452,8 +453,8 @@
 
     @Nullable
     public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai,
-            @PackageManager.ApplicationInfoFlags int flags, @NonNull FrameworkPackageUserState state,
-            int userId) {
+            @PackageManager.ApplicationInfoFlags long flags,
+            @NonNull FrameworkPackageUserState state, int userId) {
         if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) {
             return null;
         }
@@ -469,7 +470,7 @@
 
     @Nullable
     public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a,
-            @PackageManager.ComponentInfoFlags int flags, @NonNull FrameworkPackageUserState state,
+            @PackageManager.ComponentInfoFlags long flags, @NonNull FrameworkPackageUserState state,
             int userId) {
         if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) {
             return null;
@@ -484,7 +485,7 @@
 
     @Nullable
     public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a,
-            @PackageManager.ComponentInfoFlags int flags, FrameworkPackageUserState state,
+            @PackageManager.ComponentInfoFlags long flags, FrameworkPackageUserState state,
             @Nullable ApplicationInfo applicationInfo, int userId) {
         if (a == null) return null;
         if (!checkUseInstalled(pkg, state, flags)) {
@@ -504,12 +505,12 @@
      * This bypasses critical checks that are necessary for usage with data passed outside of system
      * server.
      * <p>
-     * Prefer {@link #generateActivityInfo(ParsingPackageRead, ParsedActivity, int,
+     * Prefer {@link #generateActivityInfo(ParsingPackageRead, ParsedActivity, long,
      * FrameworkPackageUserState, ApplicationInfo, int)}.
      */
     @NonNull
     public static ActivityInfo generateActivityInfoUnchecked(@NonNull ParsedActivity a,
-            @PackageManager.ComponentInfoFlags int flags,
+            @PackageManager.ComponentInfoFlags long flags,
             @NonNull ApplicationInfo applicationInfo) {
         // Make shallow copies so we can store the metadata safely
         ActivityInfo ai = new ActivityInfo();
@@ -550,13 +551,14 @@
 
     @Nullable
     public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a,
-            @PackageManager.ComponentInfoFlags int flags, FrameworkPackageUserState state, int userId) {
+            @PackageManager.ComponentInfoFlags long flags, FrameworkPackageUserState state,
+            int userId) {
         return generateActivityInfo(pkg, a, flags, state, null, userId);
     }
 
     @Nullable
     public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s,
-            @PackageManager.ComponentInfoFlags int flags, FrameworkPackageUserState state,
+            @PackageManager.ComponentInfoFlags long flags, FrameworkPackageUserState state,
             @Nullable ApplicationInfo applicationInfo, int userId) {
         if (s == null) return null;
         if (!checkUseInstalled(pkg, state, flags)) {
@@ -576,12 +578,12 @@
      * This bypasses critical checks that are necessary for usage with data passed outside of system
      * server.
      * <p>
-     * Prefer {@link #generateServiceInfo(ParsingPackageRead, ParsedService, int, FrameworkPackageUserState,
-     * ApplicationInfo, int)}.
+     * Prefer {@link #generateServiceInfo(ParsingPackageRead, ParsedService, long,
+     * FrameworkPackageUserState, ApplicationInfo, int)}.
      */
     @NonNull
     public static ServiceInfo generateServiceInfoUnchecked(@NonNull ParsedService s,
-            @PackageManager.ComponentInfoFlags int flags,
+            @PackageManager.ComponentInfoFlags long flags,
             @NonNull ApplicationInfo applicationInfo) {
         // Make shallow copies so we can store the metadata safely
         ServiceInfo si = new ServiceInfo();
@@ -600,13 +602,14 @@
 
     @Nullable
     public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s,
-            @PackageManager.ComponentInfoFlags int flags, FrameworkPackageUserState state, int userId) {
+            @PackageManager.ComponentInfoFlags long flags, FrameworkPackageUserState state,
+            int userId) {
         return generateServiceInfo(pkg, s, flags, state, null, userId);
     }
 
     @Nullable
     public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p,
-            @PackageManager.ComponentInfoFlags int flags, FrameworkPackageUserState state,
+            @PackageManager.ComponentInfoFlags long flags, FrameworkPackageUserState state,
             @Nullable ApplicationInfo applicationInfo, int userId) {
         if (p == null) return null;
         if (!checkUseInstalled(pkg, state, flags)) {
@@ -626,12 +629,12 @@
      * This bypasses critical checks that are necessary for usage with data passed outside of system
      * server.
      * <p>
-     * Prefer {@link #generateProviderInfo(ParsingPackageRead, ParsedProvider, int,
+     * Prefer {@link #generateProviderInfo(ParsingPackageRead, ParsedProvider, long,
      * FrameworkPackageUserState, ApplicationInfo, int)}.
      */
     @NonNull
     public static ProviderInfo generateProviderInfoUnchecked(@NonNull ParsedProvider p,
-            @PackageManager.ComponentInfoFlags int flags,
+            @PackageManager.ComponentInfoFlags long flags,
             @NonNull ApplicationInfo applicationInfo) {
         // Make shallow copies so we can store the metadata safely
         ProviderInfo pi = new ProviderInfo();
@@ -661,17 +664,18 @@
 
     @Nullable
     public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p,
-            @PackageManager.ComponentInfoFlags int flags, FrameworkPackageUserState state, int userId) {
+            @PackageManager.ComponentInfoFlags long flags, FrameworkPackageUserState state,
+            int userId) {
         return generateProviderInfo(pkg, p, flags, state, null, userId);
     }
 
     /**
-     * @param assignUserFields see {@link #generateApplicationInfoUnchecked(ParsingPackageRead, int,
-     *                         FrameworkPackageUserState, int, boolean)}
+     * @param assignUserFields see {@link #generateApplicationInfoUnchecked(ParsingPackageRead,
+     * long, FrameworkPackageUserState, int, boolean)}
      */
     @Nullable
     public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
-            ParsingPackageRead pkg, @PackageManager.ComponentInfoFlags int flags, int userId,
+            ParsingPackageRead pkg, @PackageManager.ComponentInfoFlags long flags, int userId,
             boolean assignUserFields) {
         if (i == null) return null;
 
@@ -702,7 +706,7 @@
 
     @Nullable
     public static PermissionInfo generatePermissionInfo(ParsedPermission p,
-            @PackageManager.ComponentInfoFlags int flags) {
+            @PackageManager.ComponentInfoFlags long flags) {
         if (p == null) return null;
 
         PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission());
@@ -725,7 +729,7 @@
 
     @Nullable
     public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg,
-            @PackageManager.ComponentInfoFlags int flags) {
+            @PackageManager.ComponentInfoFlags long flags) {
         if (pg == null) return null;
 
         PermissionGroupInfo pgi = new PermissionGroupInfo(
@@ -753,8 +757,8 @@
         return new Attribution(pa.getTag(), pa.getLabel());
     }
 
-    private static boolean checkUseInstalledOrHidden(int flags, @NonNull FrameworkPackageUserState state,
-            @Nullable ApplicationInfo appInfo) {
+    private static boolean checkUseInstalledOrHidden(long flags,
+            @NonNull FrameworkPackageUserState state, @Nullable ApplicationInfo appInfo) {
         // Returns false if the package is hidden system app until installed.
         if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
                 && !state.isInstalled()
@@ -882,8 +886,8 @@
         return privateFlagsExt;
     }
 
-    private static boolean checkUseInstalled(ParsingPackageRead pkg, FrameworkPackageUserState state,
-            @PackageManager.PackageInfoFlags int flags) {
+    private static boolean checkUseInstalled(ParsingPackageRead pkg,
+            FrameworkPackageUserState state, @PackageManager.PackageInfoFlags long flags) {
         // If available for the target user
         return PackageUserStateUtils.isAvailable(state, flags);
     }
diff --git a/core/java/android/content/pm/parsing/component/ComponentParseUtils.java b/core/java/android/content/pm/parsing/component/ComponentParseUtils.java
index 1ac9739..0334601 100644
--- a/core/java/android/content/pm/parsing/component/ComponentParseUtils.java
+++ b/core/java/android/content/pm/parsing/component/ComponentParseUtils.java
@@ -170,13 +170,13 @@
     }
 
     public static boolean isMatch(FrameworkPackageUserState state, boolean isSystem,
-            boolean isPackageEnabled, ParsedMainComponent component, int flags) {
+            boolean isPackageEnabled, ParsedMainComponent component, long flags) {
         return PackageUserStateUtils.isMatch(state, isSystem, isPackageEnabled,
                 component.isEnabled(), component.isDirectBootAware(), component.getName(), flags);
     }
 
     public static boolean isEnabled(FrameworkPackageUserState state, boolean isPackageEnabled,
-            ParsedMainComponent parsedComponent, int flags) {
+            ParsedMainComponent parsedComponent, long flags) {
         return PackageUserStateUtils.isEnabled(state, isPackageEnabled, parsedComponent.isEnabled(),
                 parsedComponent.getName(), flags);
     }
diff --git a/core/java/android/content/pm/pkg/PackageUserStateUtils.java b/core/java/android/content/pm/pkg/PackageUserStateUtils.java
index 9a800b0..468bff1 100644
--- a/core/java/android/content/pm/pkg/PackageUserStateUtils.java
+++ b/core/java/android/content/pm/pkg/PackageUserStateUtils.java
@@ -34,15 +34,15 @@
     private static final boolean DEBUG = false;
     private static final String TAG = "PackageUserStateUtils";
 
-    public static boolean isMatch(@NonNull FrameworkPackageUserState state, ComponentInfo componentInfo,
-            int flags) {
+    public static boolean isMatch(@NonNull FrameworkPackageUserState state,
+            ComponentInfo componentInfo, long flags) {
         return isMatch(state, componentInfo.applicationInfo.isSystemApp(),
                 componentInfo.applicationInfo.enabled, componentInfo.enabled,
                 componentInfo.directBootAware, componentInfo.name, flags);
     }
 
     public static boolean isMatch(@NonNull FrameworkPackageUserState state, boolean isSystem,
-            boolean isPackageEnabled, ParsedMainComponent component, int flags) {
+            boolean isPackageEnabled, ParsedMainComponent component, long flags) {
         return isMatch(state, isSystem, isPackageEnabled, component.isEnabled(),
                 component.isDirectBootAware(), component.getName(), flags);
     }
@@ -58,7 +58,7 @@
      */
     public static boolean isMatch(@NonNull FrameworkPackageUserState state, boolean isSystem,
             boolean isPackageEnabled, boolean isComponentEnabled,
-            boolean isComponentDirectBootAware, String componentName, int flags) {
+            boolean isComponentDirectBootAware, String componentName, long flags) {
         final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
         if (!isAvailable(state, flags) && !(isSystem && matchUninstalled)) {
             return reportIfDebug(false, flags);
@@ -81,7 +81,7 @@
         return reportIfDebug(matchesUnaware || matchesAware, flags);
     }
 
-    public static boolean isAvailable(@NonNull FrameworkPackageUserState state, int flags) {
+    public static boolean isAvailable(@NonNull FrameworkPackageUserState state, long flags) {
         // True if it is installed for this user and it is not hidden. If it is hidden,
         // still return true if the caller requested MATCH_UNINSTALLED_PACKAGES
         final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0;
@@ -91,7 +91,7 @@
                 && (!state.isHidden() || matchUninstalled));
     }
 
-    public static boolean reportIfDebug(boolean result, int flags) {
+    public static boolean reportIfDebug(boolean result, long flags) {
         if (DEBUG && !result) {
             Slog.i(TAG, "No match!; flags: "
                     + DebugUtils.flagsToString(PackageManager.class, "MATCH_", flags) + " "
@@ -101,13 +101,13 @@
     }
 
     public static boolean isEnabled(@NonNull FrameworkPackageUserState state, ComponentInfo componentInfo,
-            int flags) {
+            long flags) {
         return isEnabled(state, componentInfo.applicationInfo.enabled, componentInfo.enabled,
                 componentInfo.name, flags);
     }
 
     public static boolean isEnabled(@NonNull FrameworkPackageUserState state, boolean isPackageEnabled,
-            ParsedMainComponent parsedComponent, int flags) {
+            ParsedMainComponent parsedComponent, long flags) {
         return isEnabled(state, isPackageEnabled, parsedComponent.isEnabled(),
                 parsedComponent.getName(), flags);
     }
@@ -115,8 +115,9 @@
     /**
      * Test if the given component is considered enabled.
      */
-    public static boolean isEnabled(@NonNull FrameworkPackageUserState state, boolean isPackageEnabled,
-            boolean isComponentEnabled, String componentName, int flags) {
+    public static boolean isEnabled(@NonNull FrameworkPackageUserState state,
+            boolean isPackageEnabled, boolean isComponentEnabled, String componentName,
+            long flags) {
         if ((flags & MATCH_DISABLED_COMPONENTS) != 0) {
             return true;
         }
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 83e1061..2985c75 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.graphics.Point;
 import android.hardware.SensorManager;
+import android.media.projection.IMediaProjection;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.PowerManager;
@@ -380,6 +381,31 @@
     public abstract void onEarlyInteractivityChange(boolean interactive);
 
     /**
+     * A special API for creates a virtual display with a DisplayPolicyController in system_server.
+     * <p>
+     * If this method is called without original calling uid, the caller must enforce the
+     * corresponding permissions according to the flags.
+     *   {@link android.Manifest.permission#CAPTURE_VIDEO_OUTPUT}
+     *   {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT}
+     *   {@link android.Manifest.permission#ADD_TRUSTED_DISPLAY}
+     *   {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW}
+     * </p>
+     *
+     * @param virtualDisplayConfig The arguments for the virtual display configuration. See
+     *                             {@link VirtualDisplayConfig} for using it.
+     * @param callback Callback to call when the virtual display's state changes, or null if none.
+     * @param projection MediaProjection token.
+     * @param packageName The package name of the app.
+     * @param controller The DisplayWindowPolicyControl that can control what contents are
+     *                   allowed to be displayed.
+     * @return The newly created virtual display id , or {@link Display#INVALID_DISPLAY} if the
+     * virtual display cannot be created.
+     */
+    public abstract int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
+            IVirtualDisplayCallback callback, IMediaProjection projection, String packageName,
+            DisplayWindowPolicyController controller);
+
+    /**
      * Get {@link DisplayWindowPolicyController} associated to the {@link DisplayInfo#displayId}
      *
      * @param displayId The id of the display.
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index e5d8620..6f0c944 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -1016,9 +1016,8 @@
     }
 
     /**
-     * Queries the framework about whether any physical keys exist on the
-     * any keyboard attached to the device that are capable of producing the given
-     * array of key codes.
+     * Queries the framework about whether any physical keys exist on any currently attached input
+     * devices that are capable of producing the given array of key codes.
      *
      * @param keyCodes The array of key codes to query.
      * @return A new array of the same size as the key codes array whose elements
@@ -1032,11 +1031,10 @@
     }
 
     /**
-     * Queries the framework about whether any physical keys exist on the
-     * any keyboard attached to the device that are capable of producing the given
-     * array of key codes.
+     * Queries the framework about whether any physical keys exist on the specified input device
+     * that are capable of producing the given array of key codes.
      *
-     * @param id The id of the device to query.
+     * @param id The id of the input device to query or -1 to consult all devices.
      * @param keyCodes The array of key codes to query.
      * @return A new array of the same size as the key codes array whose elements are set to true
      * if the given device could produce the corresponding key code at the same index in the key
diff --git a/core/java/android/os/CombinedVibration.java b/core/java/android/os/CombinedVibration.java
index aff55af..5f2c113 100644
--- a/core/java/android/os/CombinedVibration.java
+++ b/core/java/android/os/CombinedVibration.java
@@ -110,6 +110,20 @@
     @TestApi
     public abstract long getDuration();
 
+    /**
+     * Returns true if this effect could represent a touch haptic feedback.
+     *
+     * <p>It is strongly recommended that an instance of {@link VibrationAttributes} is specified
+     * for each vibration, with the correct usage. When a vibration is played with usage UNKNOWN,
+     * then this method will be used to classify the most common use case and make sure they are
+     * covered by the user settings for "Touch feedback".
+     *
+     * @hide
+     */
+    public boolean isHapticFeedbackCandidate() {
+        return false;
+    }
+
     /** @hide */
     public abstract void validate();
 
@@ -314,6 +328,12 @@
 
         /** @hide */
         @Override
+        public boolean isHapticFeedbackCandidate() {
+            return mEffect.isHapticFeedbackCandidate();
+        }
+
+        /** @hide */
+        @Override
         public void validate() {
             mEffect.validate();
         }
@@ -431,6 +451,17 @@
 
         /** @hide */
         @Override
+        public boolean isHapticFeedbackCandidate() {
+            for (int i = 0; i < mEffects.size(); i++) {
+                if (!mEffects.valueAt(i).isHapticFeedbackCandidate()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /** @hide */
+        @Override
         public void validate() {
             Preconditions.checkArgument(mEffects.size() > 0,
                     "There should be at least one effect set for a combined effect");
@@ -513,6 +544,9 @@
      */
     @TestApi
     public static final class Sequential extends CombinedVibration {
+        // If a vibration is playing more than 3 effects, it's probably not haptic feedback
+        private static final long MAX_HAPTIC_FEEDBACK_SEQUENCE_SIZE = 3;
+
         private final List<CombinedVibration> mEffects;
         private final List<Integer> mDelays;
 
@@ -575,6 +609,21 @@
 
         /** @hide */
         @Override
+        public boolean isHapticFeedbackCandidate() {
+            final int effectCount = mEffects.size();
+            if (effectCount > MAX_HAPTIC_FEEDBACK_SEQUENCE_SIZE) {
+                return false;
+            }
+            for (int i = 0; i < effectCount; i++) {
+                if (!mEffects.get(i).isHapticFeedbackCandidate()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /** @hide */
+        @Override
         public void validate() {
             Preconditions.checkArgument(mEffects.size() > 0,
                     "There should be at least one effect set for a combined effect");
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index a828268..d0d6cb7 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -196,9 +196,6 @@
             return;
         }
         CombinedVibration combinedEffect = CombinedVibration.createParallel(effect);
-        // TODO(b/185351540): move this into VibratorManagerService once the touch vibration
-        // heuristics is fixed and works for CombinedVibration. Make sure it's always applied.
-        attributes = new VibrationAttributes.Builder(attributes, effect).build();
         mVibratorManager.vibrate(uid, opPkg, combinedEffect, reason, attributes);
     }
 
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index e5622a3..c690df2 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -223,9 +223,6 @@
             CombinedVibration combined = CombinedVibration.startParallel()
                     .addVibrator(mVibratorInfo.getId(), vibe)
                     .combine();
-            // TODO(b/185351540): move this into VibratorManagerService once the touch vibration
-            // heuristics is fixed and works for CombinedVibration. Make sure it's always applied.
-            attributes = new VibrationAttributes.Builder(attributes, vibe).build();
             SystemVibratorManager.this.vibrate(uid, opPkg, combined, reason, attributes);
         }
 
diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java
index 36cdfcc..9612ca6 100644
--- a/core/java/android/os/VibrationAttributes.java
+++ b/core/java/android/os/VibrationAttributes.java
@@ -21,9 +21,6 @@
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.media.AudioAttributes;
-import android.os.vibrator.PrebakedSegment;
-import android.os.vibrator.VibrationEffectSegment;
-import android.util.Slog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -156,9 +153,6 @@
      */
     public static final int FLAG_ALL_SUPPORTED = FLAG_BYPASS_INTERRUPTION_POLICY;
 
-    // If a vibration is playing for longer than 5s, it's probably not haptic feedback
-    private static final long MAX_HAPTIC_FEEDBACK_DURATION = 5000;
-
     /** Creates a new {@link VibrationAttributes} instance with given usage. */
     public static @NonNull VibrationAttributes createForUsage(int usage) {
         return new VibrationAttributes.Builder().setUsage(usage).build();
@@ -359,67 +353,6 @@
             setFlags(audio);
         }
 
-        /**
-         * Constructs a new Builder from AudioAttributes and a VibrationEffect to infer usage.
-         * @hide
-         */
-        @TestApi
-        public Builder(@NonNull AudioAttributes audio, @NonNull VibrationEffect effect) {
-            this(audio);
-            applyHapticFeedbackHeuristics(effect);
-        }
-
-        /**
-         * Constructs a new Builder from VibrationAttributes and a VibrationEffect to infer usage.
-         * @hide
-         */
-        @TestApi
-        public Builder(@NonNull VibrationAttributes vib, @NonNull VibrationEffect effect) {
-            this(vib);
-            applyHapticFeedbackHeuristics(effect);
-        }
-
-        private void applyHapticFeedbackHeuristics(@Nullable VibrationEffect effect) {
-            if (effect != null) {
-                PrebakedSegment prebaked = extractPrebakedSegment(effect);
-                if (mUsage == USAGE_UNKNOWN && prebaked != null) {
-                    switch (prebaked.getEffectId()) {
-                        case VibrationEffect.EFFECT_CLICK:
-                        case VibrationEffect.EFFECT_DOUBLE_CLICK:
-                        case VibrationEffect.EFFECT_HEAVY_CLICK:
-                        case VibrationEffect.EFFECT_TEXTURE_TICK:
-                        case VibrationEffect.EFFECT_TICK:
-                        case VibrationEffect.EFFECT_POP:
-                        case VibrationEffect.EFFECT_THUD:
-                            mUsage = USAGE_TOUCH;
-                            break;
-                        default:
-                            Slog.w(TAG, "Unknown prebaked vibration effect, assuming it isn't "
-                                    + "haptic feedback");
-                    }
-                }
-                final long duration = effect.getDuration();
-                if (mUsage == USAGE_UNKNOWN && duration >= 0
-                        && duration < MAX_HAPTIC_FEEDBACK_DURATION) {
-                    mUsage = USAGE_TOUCH;
-                }
-            }
-        }
-
-        @Nullable
-        private PrebakedSegment extractPrebakedSegment(VibrationEffect effect) {
-            if (effect instanceof VibrationEffect.Composed) {
-                VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
-                if (composed.getSegments().size() == 1) {
-                    VibrationEffectSegment segment = composed.getSegments().get(0);
-                    if (segment instanceof PrebakedSegment) {
-                        return (PrebakedSegment) segment;
-                    }
-                }
-            }
-            return null;
-        }
-
         private void setUsage(@NonNull AudioAttributes audio) {
             mOriginalAudioUsage = audio.getUsage();
             switch (audio.getUsage()) {
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index a0cbbfe..5758a4e 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -53,7 +53,10 @@
 public abstract class VibrationEffect implements Parcelable {
     // Stevens' coefficient to scale the perceived vibration intensity.
     private static final float SCALE_GAMMA = 0.65f;
-
+    // If a vibration is playing for longer than 1s, it's probably not haptic feedback
+    private static final long MAX_HAPTIC_FEEDBACK_DURATION = 1000;
+    // If a vibration is playing more than 3 constants, it's probably not haptic feedback
+    private static final long MAX_HAPTIC_FEEDBACK_COMPOSITION_SIZE = 3;
 
     /**
      * The default vibration strength of the device.
@@ -439,6 +442,20 @@
     public abstract long getDuration();
 
     /**
+     * Returns true if this effect could represent a touch haptic feedback.
+     *
+     * <p>It is strongly recommended that an instance of {@link VibrationAttributes} is specified
+     * for each vibration, with the correct usage. When a vibration is played with usage UNKNOWN,
+     * then this method will be used to classify the most common use case and make sure they are
+     * covered by the user settings for "Touch feedback".
+     *
+     * @hide
+     */
+    public boolean isHapticFeedbackCandidate() {
+        return false;
+    }
+
+    /**
      * Resolve default values into integer amplitude numbers.
      *
      * @param defaultAmplitude the default amplitude to apply, must be between 0 and
@@ -582,6 +599,7 @@
             return mRepeatIndex;
         }
 
+        /** @hide */
         @Override
         public void validate() {
             int segmentCount = mSegments.size();
@@ -620,6 +638,37 @@
             return totalDuration;
         }
 
+        /** @hide */
+        @Override
+        public boolean isHapticFeedbackCandidate() {
+            long totalDuration = getDuration();
+            if (totalDuration > MAX_HAPTIC_FEEDBACK_DURATION) {
+                // Vibration duration is known and is longer than the max duration used to classify
+                // haptic feedbacks (or repeating indefinitely with duration == Long.MAX_VALUE).
+                return false;
+            }
+            int segmentCount = mSegments.size();
+            if (segmentCount > MAX_HAPTIC_FEEDBACK_COMPOSITION_SIZE) {
+                // Vibration has some prebaked or primitive constants, it should be limited to the
+                // max composition size used to classify haptic feedbacks.
+                return false;
+            }
+            totalDuration = 0;
+            for (int i = 0; i < segmentCount; i++) {
+                if (!mSegments.get(i).isHapticFeedbackCandidate()) {
+                    // There is at least one segment that is not a candidate for a haptic feedback.
+                    return false;
+                }
+                long segmentDuration = mSegments.get(i).getDuration();
+                if (segmentDuration > 0) {
+                    totalDuration += segmentDuration;
+                }
+            }
+            // Vibration might still have some ramp or step segments, check the known duration.
+            return totalDuration <= MAX_HAPTIC_FEEDBACK_DURATION;
+        }
+
+        /** @hide */
         @NonNull
         @Override
         public Composed resolve(int defaultAmplitude) {
@@ -636,6 +685,7 @@
             return resolved;
         }
 
+        /** @hide */
         @NonNull
         @Override
         public Composed scale(float scaleFactor) {
@@ -652,6 +702,7 @@
             return scaled;
         }
 
+        /** @hide */
         @NonNull
         @Override
         public Composed applyEffectStrength(int effectStrength) {
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 75234db..c67c82e 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -493,7 +493,7 @@
         vibrate(vibe,
                 attributes == null
                         ? new VibrationAttributes.Builder().build()
-                        : new VibrationAttributes.Builder(attributes, vibe).build());
+                        : new VibrationAttributes.Builder(attributes).build());
     }
 
     /**
diff --git a/core/java/android/os/vibrator/PrebakedSegment.java b/core/java/android/os/vibrator/PrebakedSegment.java
index 78b4346..30f5a5c 100644
--- a/core/java/android/os/vibrator/PrebakedSegment.java
+++ b/core/java/android/os/vibrator/PrebakedSegment.java
@@ -67,17 +67,38 @@
         return -1;
     }
 
+    /** @hide */
+    @Override
+    public boolean isHapticFeedbackCandidate() {
+        switch (mEffectId) {
+            case VibrationEffect.EFFECT_CLICK:
+            case VibrationEffect.EFFECT_DOUBLE_CLICK:
+            case VibrationEffect.EFFECT_HEAVY_CLICK:
+            case VibrationEffect.EFFECT_POP:
+            case VibrationEffect.EFFECT_TEXTURE_TICK:
+            case VibrationEffect.EFFECT_THUD:
+            case VibrationEffect.EFFECT_TICK:
+                return true;
+            default:
+                // VibrationEffect.RINGTONES are not segments that could represent a haptic feedback
+                return false;
+        }
+    }
+
+    /** @hide */
     @Override
     public boolean hasNonZeroAmplitude() {
         return true;
     }
 
+    /** @hide */
     @NonNull
     @Override
     public PrebakedSegment resolve(int defaultAmplitude) {
         return this;
     }
 
+    /** @hide */
     @NonNull
     @Override
     public PrebakedSegment scale(float scaleFactor) {
@@ -85,6 +106,7 @@
         return this;
     }
 
+    /** @hide */
     @NonNull
     @Override
     public PrebakedSegment applyEffectStrength(int effectStrength) {
@@ -105,16 +127,17 @@
         }
     }
 
+    /** @hide */
     @Override
     public void validate() {
         switch (mEffectId) {
             case VibrationEffect.EFFECT_CLICK:
             case VibrationEffect.EFFECT_DOUBLE_CLICK:
-            case VibrationEffect.EFFECT_TICK:
+            case VibrationEffect.EFFECT_HEAVY_CLICK:
+            case VibrationEffect.EFFECT_POP:
             case VibrationEffect.EFFECT_TEXTURE_TICK:
             case VibrationEffect.EFFECT_THUD:
-            case VibrationEffect.EFFECT_POP:
-            case VibrationEffect.EFFECT_HEAVY_CLICK:
+            case VibrationEffect.EFFECT_TICK:
                 break;
             default:
                 int[] ringtones = VibrationEffect.RINGTONES;
diff --git a/core/java/android/os/vibrator/PrimitiveSegment.java b/core/java/android/os/vibrator/PrimitiveSegment.java
index 2ef29cb..58ca978 100644
--- a/core/java/android/os/vibrator/PrimitiveSegment.java
+++ b/core/java/android/os/vibrator/PrimitiveSegment.java
@@ -67,18 +67,27 @@
         return -1;
     }
 
+    /** @hide */
+    @Override
+    public boolean isHapticFeedbackCandidate() {
+        return true;
+    }
+
+    /** @hide */
     @Override
     public boolean hasNonZeroAmplitude() {
         // Every primitive plays a vibration with a non-zero amplitude, even at scale == 0.
         return true;
     }
 
+    /** @hide */
     @NonNull
     @Override
     public PrimitiveSegment resolve(int defaultAmplitude) {
         return this;
     }
 
+    /** @hide */
     @NonNull
     @Override
     public PrimitiveSegment scale(float scaleFactor) {
@@ -86,12 +95,14 @@
                 mDelay);
     }
 
+    /** @hide */
     @NonNull
     @Override
     public PrimitiveSegment applyEffectStrength(int effectStrength) {
         return this;
     }
 
+    /** @hide */
     @Override
     public void validate() {
         Preconditions.checkArgumentInRange(mPrimitiveId, VibrationEffect.Composition.PRIMITIVE_NOOP,
diff --git a/core/java/android/os/vibrator/RampSegment.java b/core/java/android/os/vibrator/RampSegment.java
index aad87c5..3ec5636 100644
--- a/core/java/android/os/vibrator/RampSegment.java
+++ b/core/java/android/os/vibrator/RampSegment.java
@@ -87,11 +87,19 @@
         return mDuration;
     }
 
+    /** @hide */
+    @Override
+    public boolean isHapticFeedbackCandidate() {
+        return true;
+    }
+
+    /** @hide */
     @Override
     public boolean hasNonZeroAmplitude() {
         return mStartAmplitude > 0 || mEndAmplitude > 0;
     }
 
+    /** @hide */
     @Override
     public void validate() {
         Preconditions.checkArgumentNonnegative(mDuration,
@@ -100,7 +108,7 @@
         Preconditions.checkArgumentInRange(mEndAmplitude, 0f, 1f, "endAmplitude");
     }
 
-
+    /** @hide */
     @NonNull
     @Override
     public RampSegment resolve(int defaultAmplitude) {
@@ -108,6 +116,7 @@
         return this;
     }
 
+    /** @hide */
     @NonNull
     @Override
     public RampSegment scale(float scaleFactor) {
@@ -121,6 +130,7 @@
                 mDuration);
     }
 
+    /** @hide */
     @NonNull
     @Override
     public RampSegment applyEffectStrength(int effectStrength) {
diff --git a/core/java/android/os/vibrator/StepSegment.java b/core/java/android/os/vibrator/StepSegment.java
index 11209e0..69a381f 100644
--- a/core/java/android/os/vibrator/StepSegment.java
+++ b/core/java/android/os/vibrator/StepSegment.java
@@ -73,12 +73,20 @@
         return mDuration;
     }
 
+    /** @hide */
+    @Override
+    public boolean isHapticFeedbackCandidate() {
+        return true;
+    }
+
+    /** @hide */
     @Override
     public boolean hasNonZeroAmplitude() {
         // DEFAULT_AMPLITUDE == -1 is still a non-zero amplitude that will be resolved later.
         return Float.compare(mAmplitude, 0) != 0;
     }
 
+    /** @hide */
     @Override
     public void validate() {
         Preconditions.checkArgumentNonnegative(mDuration,
@@ -88,6 +96,7 @@
         }
     }
 
+    /** @hide */
     @NonNull
     @Override
     public StepSegment resolve(int defaultAmplitude) {
@@ -103,6 +112,7 @@
                 mDuration);
     }
 
+    /** @hide */
     @NonNull
     @Override
     public StepSegment scale(float scaleFactor) {
@@ -113,6 +123,7 @@
                 mDuration);
     }
 
+    /** @hide */
     @NonNull
     @Override
     public StepSegment applyEffectStrength(int effectStrength) {
diff --git a/core/java/android/os/vibrator/VibrationEffectSegment.java b/core/java/android/os/vibrator/VibrationEffectSegment.java
index 5b42845..979c447 100644
--- a/core/java/android/os/vibrator/VibrationEffectSegment.java
+++ b/core/java/android/os/vibrator/VibrationEffectSegment.java
@@ -57,10 +57,26 @@
      */
     public abstract long getDuration();
 
-    /** Returns true if this segment plays at a non-zero amplitude at some point. */
+    /**
+     * Returns true if this segment could be a haptic feedback effect candidate.
+     *
+     * @see VibrationEffect#isHapticFeedbackCandidate()
+     * @hide
+     */
+    public abstract boolean isHapticFeedbackCandidate();
+
+    /**
+     * Returns true if this segment plays at a non-zero amplitude at some point.
+     *
+     * @hide
+     */
     public abstract boolean hasNonZeroAmplitude();
 
-    /** Validates the segment, throwing exceptions if any parameter is invalid. */
+    /**
+     * Validates the segment, throwing exceptions if any parameter is invalid.
+     *
+     * @hide
+     */
     public abstract void validate();
 
     /**
@@ -68,6 +84,8 @@
      *
      * <p>This might fail with {@link IllegalArgumentException} if value is non-positive or larger
      * than {@link VibrationEffect#MAX_AMPLITUDE}.
+     *
+     * @hide
      */
     @NonNull
     public abstract <T extends VibrationEffectSegment> T resolve(int defaultAmplitude);
@@ -77,6 +95,8 @@
      *
      * @param scaleFactor scale factor to be applied to the intensity. Values within [0,1) will
      *                    scale down the intensity, values larger than 1 will scale up
+     *
+     * @hide
      */
     @NonNull
     public abstract <T extends VibrationEffectSegment> T scale(float scaleFactor);
@@ -86,6 +106,8 @@
      *
      * @param effectStrength new effect strength to be applied, one of
      *                       VibrationEffect.EFFECT_STRENGTH_*.
+     *
+     * @hide
      */
     @NonNull
     public abstract <T extends VibrationEffectSegment> T applyEffectStrength(int effectStrength);
diff --git a/core/java/android/util/DebugUtils.java b/core/java/android/util/DebugUtils.java
index ece6b35..bab2089 100644
--- a/core/java/android/util/DebugUtils.java
+++ b/core/java/android/util/DebugUtils.java
@@ -242,35 +242,49 @@
      *
      * @hide
      */
-    public static String flagsToString(Class<?> clazz, String prefix, int flags) {
+    public static String flagsToString(Class<?> clazz, String prefix, long flags) {
         final StringBuilder res = new StringBuilder();
         boolean flagsWasZero = flags == 0;
 
         for (Field field : clazz.getDeclaredFields()) {
             final int modifiers = field.getModifiers();
             if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
-                    && field.getType().equals(int.class) && field.getName().startsWith(prefix)) {
-                try {
-                    final int value = field.getInt(null);
-                    if (value == 0 && flagsWasZero) {
-                        return constNameWithoutPrefix(prefix, field);
-                    }
-                    if (value != 0 && (flags & value) == value) {
-                        flags &= ~value;
-                        res.append(constNameWithoutPrefix(prefix, field)).append('|');
-                    }
-                } catch (IllegalAccessException ignored) {
+                    && (field.getType().equals(int.class) || field.getType().equals(long.class))
+                    && field.getName().startsWith(prefix)) {
+                final long value = getFieldValue(field);
+                if (value == 0 && flagsWasZero) {
+                    return constNameWithoutPrefix(prefix, field);
+                }
+                if (value != 0 && (flags & value) == value) {
+                    flags &= ~value;
+                    res.append(constNameWithoutPrefix(prefix, field)).append('|');
                 }
             }
         }
         if (flags != 0 || res.length() == 0) {
-            res.append(Integer.toHexString(flags));
+            res.append(Long.toHexString(flags));
         } else {
             res.deleteCharAt(res.length() - 1);
         }
         return res.toString();
     }
 
+    private static long getFieldValue(Field field) {
+        // Field could be int or long
+        try {
+            final long longValue = field.getLong(null);
+            if (longValue != 0) {
+                return longValue;
+            }
+            final int intValue = field.getInt(null);
+            if (intValue != 0) {
+                return intValue;
+            }
+        } catch (IllegalAccessException ignored) {
+        }
+        return 0;
+    }
+
     /**
      * Gets human-readable representation of constants (static final values).
      *
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index aa1acc1..a6f88a7 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -709,8 +709,8 @@
     }
 
     /**
-     * Queries the framework about whether any physical keys exist on the
-     * any keyboard attached to the device that are capable of producing the given key code.
+     * Queries the framework about whether any physical keys exist on any currently attached input
+     * devices that are capable of producing the given key code.
      *
      * @param keyCode The key code to query.
      * @return True if at least one attached keyboard supports the specified key code.
@@ -720,9 +720,8 @@
     }
 
     /**
-     * Queries the framework about whether any physical keys exist on the
-     * any keyboard attached to the device that are capable of producing the given
-     * array of key codes.
+     * Queries the framework about whether any physical keys exist on any currently attached input
+     * devices that are capable of producing the given array of key codes.
      *
      * @param keyCodes The array of key codes to query.
      * @return A new array of the same size as the key codes array whose elements
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index bff813e..6a6f60e 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -512,6 +512,11 @@
      */
     public static final String DEFAULT_QR_CODE_SCANNER = "default_qr_code_scanner";
 
+    /**
+     * (boolean) Whether the task manager entrypoint is enabled.
+     */
+    public static final String TASK_MANAGER_ENABLED = "task_manager_enabled";
+
     private SystemUiDeviceConfigFlags() {
     }
 }
diff --git a/core/proto/android/app/location_time_zone_manager.proto b/core/proto/android/app/location_time_zone_manager.proto
index 891e9fc..5fdcfdf 100644
--- a/core/proto/android/app/location_time_zone_manager.proto
+++ b/core/proto/android/app/location_time_zone_manager.proto
@@ -23,6 +23,19 @@
 option java_multiple_files = true;
 option java_outer_classname = "LocationTimeZoneManagerProto";
 
+// A state enum that matches states for LocationTimeZoneProviderController. See that class for
+// details.
+enum ControllerStateEnum {
+  CONTROLLER_STATE_UNKNOWN = 0;
+  CONTROLLER_STATE_PROVIDERS_INITIALIZING = 1;
+  CONTROLLER_STATE_STOPPED = 2;
+  CONTROLLER_STATE_INITIALIZING = 3;
+  CONTROLLER_STATE_UNCERTAIN = 4;
+  CONTROLLER_STATE_CERTAIN = 5;
+  CONTROLLER_STATE_FAILED = 6;
+  CONTROLLER_STATE_DESTROYED = 7;
+}
+
 // Represents the state of the LocationTimeZoneManagerService for use in tests.
 message LocationTimeZoneManagerServiceStateProto {
   option (android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -30,6 +43,7 @@
   optional GeolocationTimeZoneSuggestionProto last_suggestion = 1;
   repeated TimeZoneProviderStateProto primary_provider_states = 2;
   repeated TimeZoneProviderStateProto secondary_provider_states = 3;
+  repeated ControllerStateEnum controller_states = 4;
 }
 
 // The state tracked for a LocationTimeZoneProvider.
diff --git a/core/tests/coretests/src/android/os/CombinedVibrationTest.java b/core/tests/coretests/src/android/os/CombinedVibrationTest.java
index 06b5d18..508856b 100644
--- a/core/tests/coretests/src/android/os/CombinedVibrationTest.java
+++ b/core/tests/coretests/src/android/os/CombinedVibrationTest.java
@@ -125,6 +125,12 @@
                 VibrationEffect.createOneShot(1, 1)).getDuration());
         assertEquals(-1, CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK)).getDuration());
+        assertEquals(-1, CombinedVibration.createParallel(
+                        VibrationEffect.startComposition()
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 100)
+                                .compose())
+                .getDuration());
         assertEquals(Long.MAX_VALUE, CombinedVibration.createParallel(
                 VibrationEffect.createWaveform(
                         new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)).getDuration());
@@ -175,6 +181,83 @@
     }
 
     @Test
+    public void testIsHapticFeedbackCandidateMono() {
+        assertTrue(CombinedVibration.createParallel(
+                VibrationEffect.createOneShot(1, 1)).isHapticFeedbackCandidate());
+        assertTrue(CombinedVibration.createParallel(
+                VibrationEffect.get(VibrationEffect.EFFECT_CLICK)).isHapticFeedbackCandidate());
+        assertTrue(CombinedVibration.createParallel(
+                        VibrationEffect.startComposition()
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 100)
+                                .compose())
+                .isHapticFeedbackCandidate());
+        // Too long to be classified as a haptic feedback.
+        assertFalse(CombinedVibration.createParallel(
+                VibrationEffect.createOneShot(10_000, 1)).isHapticFeedbackCandidate());
+        // Repeating vibrations should not be classified as a haptic feedback.
+        assertFalse(CombinedVibration.createParallel(
+                VibrationEffect.createWaveform(new long[]{1}, new int[]{1}, 0))
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidateStereo() {
+        assertTrue(CombinedVibration.startParallel()
+                .addVibrator(1, VibrationEffect.createOneShot(1, 1))
+                .addVibrator(2, VibrationEffect.createWaveform(new long[]{6}, new int[]{1}, -1))
+                .combine()
+                .isHapticFeedbackCandidate());
+        assertTrue(CombinedVibration.startParallel()
+                .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(2,
+                        VibrationEffect.startComposition()
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 100)
+                                .compose())
+                .combine()
+                .isHapticFeedbackCandidate());
+        // Repeating vibrations should not be classified as a haptic feedback.
+        assertFalse(CombinedVibration.startParallel()
+                .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(2, VibrationEffect.createWaveform(new long[]{1}, new int[]{1}, 0))
+                .combine()
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidateSequential() {
+        assertTrue(CombinedVibration.startSequential()
+                .addNext(1, VibrationEffect.createOneShot(10, 10), 10)
+                .addNext(2, VibrationEffect.createWaveform(new long[]{5}, new int[]{1}, -1))
+                .combine()
+                .isHapticFeedbackCandidate());
+        assertTrue(CombinedVibration.startSequential()
+                .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addNext(2,
+                        VibrationEffect.startComposition()
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SLOW_RISE)
+                                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL)
+                                .compose())
+                .combine()
+                .isHapticFeedbackCandidate());
+        // Repeating vibrations should not be classified as a haptic feedback.
+        assertFalse(CombinedVibration.startSequential()
+                .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addNext(2, VibrationEffect.createWaveform(new long[]{1}, new int[]{1}, 0))
+                .combine()
+                .isHapticFeedbackCandidate());
+        // Too many effects to be classified as a haptic feedback.
+        assertFalse(CombinedVibration.startSequential()
+                .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+                .addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK))
+                .addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_THUD))
+                .combine()
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
     public void testHasVibratorMono_returnsTrueForAnyVibrator() {
         CombinedVibration effect = CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
diff --git a/core/tests/coretests/src/android/os/VibrationEffectTest.java b/core/tests/coretests/src/android/os/VibrationEffectTest.java
index 6cbfffc..781564b 100644
--- a/core/tests/coretests/src/android/os/VibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/VibrationEffectTest.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
@@ -312,8 +313,106 @@
         assertTrue(100 / 255f > ((StepSegment) scaledDown.getSegments().get(1)).getAmplitude());
     }
 
+
+    @Test
+    public void testDuration() {
+        assertEquals(1, VibrationEffect.createOneShot(1, 1).getDuration());
+        assertEquals(-1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK).getDuration());
+        assertEquals(-1,
+                VibrationEffect.startComposition()
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 100)
+                        .compose()
+                        .getDuration());
+        assertEquals(6, VibrationEffect.createWaveform(
+                new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1).getDuration());
+        assertEquals(Long.MAX_VALUE, VibrationEffect.createWaveform(
+                new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0).getDuration());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_repeatingEffects_notCandidates() {
+        assertFalse(VibrationEffect.createWaveform(
+                new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0).isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_longEffects_notCandidates() {
+        assertFalse(VibrationEffect.createOneShot(1500, 255).isHapticFeedbackCandidate());
+        assertFalse(VibrationEffect.createWaveform(
+                new long[]{200, 200, 700}, new int[]{1, 2, 3}, -1).isHapticFeedbackCandidate());
+        assertFalse(VibrationEffect.startWaveform()
+                .addRamp(1, 500)
+                .addStep(1, 200)
+                .addRamp(0, 500)
+                .build()
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_shortEffects_areCandidates() {
+        assertTrue(VibrationEffect.createOneShot(500, 255).isHapticFeedbackCandidate());
+        assertTrue(VibrationEffect.createWaveform(
+                new long[]{100, 200, 300}, new int[]{1, 2, 3}, -1).isHapticFeedbackCandidate());
+        assertTrue(VibrationEffect.startWaveform()
+                .addRamp(1, 300)
+                .addStep(1, 200)
+                .addRamp(0, 300)
+                .build()
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_longCompositions_notCandidates() {
+        assertFalse(VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SLOW_RISE)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL)
+                .compose()
+                .isHapticFeedbackCandidate());
+
+        assertFalse(VibrationEffect.startComposition()
+                .addEffect(VibrationEffect.createOneShot(1500, 255))
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK)
+                .compose()
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_shortCompositions_areCandidates() {
+        assertTrue(VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SLOW_RISE)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .compose()
+                .isHapticFeedbackCandidate());
+
+        assertTrue(VibrationEffect.startComposition()
+                .addEffect(VibrationEffect.createOneShot(100, 255))
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK)
+                .compose()
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_prebakedRingtones_notCandidates() {
+        assertFalse(VibrationEffect.get(
+                VibrationEffect.RINGTONES[1]).isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_prebakedNotRingtoneConstants_areCandidates() {
+        assertTrue(VibrationEffect.get(VibrationEffect.EFFECT_CLICK).isHapticFeedbackCandidate());
+        assertTrue(VibrationEffect.get(VibrationEffect.EFFECT_THUD).isHapticFeedbackCandidate());
+        assertTrue(VibrationEffect.get(VibrationEffect.EFFECT_TICK).isHapticFeedbackCandidate());
+    }
+
     private Resources mockRingtoneResources() {
-        return mockRingtoneResources(new String[] {
+        return mockRingtoneResources(new String[]{
                 RINGTONE_URI_1,
                 RINGTONE_URI_2,
                 RINGTONE_URI_3
diff --git a/core/tests/coretests/src/android/os/VibratorTest.java b/core/tests/coretests/src/android/os/VibratorTest.java
index 6b69b3f..bdd76a5 100644
--- a/core/tests/coretests/src/android/os/VibratorTest.java
+++ b/core/tests/coretests/src/android/os/VibratorTest.java
@@ -250,17 +250,4 @@
         VibrationAttributes vibrationAttributes = captor.getValue();
         assertEquals(new VibrationAttributes.Builder().build(), vibrationAttributes);
     }
-
-    @Test
-    public void vibrate_withoutAudioAttributesAndLongEffect_hasUnknownUsage() {
-        mVibratorSpy.vibrate(VibrationEffect.createOneShot(10_000, 255));
-
-        ArgumentCaptor<VibrationAttributes> captor = ArgumentCaptor.forClass(
-                VibrationAttributes.class);
-        verify(mVibratorSpy).vibrate(anyInt(), anyString(), any(), isNull(), captor.capture());
-
-        VibrationAttributes vibrationAttributes = captor.getValue();
-        assertEquals(VibrationAttributes.USAGE_UNKNOWN, vibrationAttributes.getUsage());
-        assertEquals(AudioAttributes.USAGE_UNKNOWN, vibrationAttributes.getAudioUsage());
-    }
 }
diff --git a/core/tests/coretests/src/android/os/vibrator/PrebakedSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/PrebakedSegmentTest.java
index de80812..a0e1f43 100644
--- a/core/tests/coretests/src/android/os/vibrator/PrebakedSegmentTest.java
+++ b/core/tests/coretests/src/android/os/vibrator/PrebakedSegmentTest.java
@@ -17,6 +17,7 @@
 package android.os.vibrator;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertSame;
 import static junit.framework.Assert.assertTrue;
 
@@ -105,4 +106,49 @@
                 VibrationEffect.EFFECT_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
         assertSame(prebaked, prebaked.scale(0.5f));
     }
+
+    @Test
+    public void testDuration() {
+        assertEquals(-1, new PrebakedSegment(
+                VibrationEffect.EFFECT_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .getDuration());
+        assertEquals(-1, new PrebakedSegment(
+                VibrationEffect.EFFECT_TICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .getDuration());
+        assertEquals(-1, new PrebakedSegment(
+                VibrationEffect.EFFECT_DOUBLE_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .getDuration());
+        assertEquals(-1, new PrebakedSegment(
+                VibrationEffect.EFFECT_THUD, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .getDuration());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_prebakedConstants_areCandidates() {
+        assertTrue(new PrebakedSegment(
+                VibrationEffect.EFFECT_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .isHapticFeedbackCandidate());
+        assertTrue(new PrebakedSegment(
+                VibrationEffect.EFFECT_TICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .isHapticFeedbackCandidate());
+        assertTrue(new PrebakedSegment(
+                VibrationEffect.EFFECT_DOUBLE_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .isHapticFeedbackCandidate());
+        assertTrue(new PrebakedSegment(
+                VibrationEffect.EFFECT_HEAVY_CLICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .isHapticFeedbackCandidate());
+        assertTrue(new PrebakedSegment(
+                VibrationEffect.EFFECT_THUD, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .isHapticFeedbackCandidate());
+        assertTrue(new PrebakedSegment(
+                VibrationEffect.EFFECT_TEXTURE_TICK, true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .isHapticFeedbackCandidate());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_prebakedRingtones_notCandidates() {
+        assertFalse(new PrebakedSegment(
+                VibrationEffect.RINGTONES[1], true, VibrationEffect.EFFECT_STRENGTH_MEDIUM)
+                .isHapticFeedbackCandidate());
+    }
 }
diff --git a/core/tests/coretests/src/android/os/vibrator/PrimitiveSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/PrimitiveSegmentTest.java
index 538655b..a690553 100644
--- a/core/tests/coretests/src/android/os/vibrator/PrimitiveSegmentTest.java
+++ b/core/tests/coretests/src/android/os/vibrator/PrimitiveSegmentTest.java
@@ -127,4 +127,28 @@
         assertEquals(0f, initial.scale(1.5f).scale(2 / 3f).getScale(), TOLERANCE);
         assertEquals(0f, initial.scale(0.8f).scale(1.25f).getScale(), TOLERANCE);
     }
+
+    @Test
+    public void testDuration() {
+        assertEquals(-1, new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_NOOP, 1, 10).getDuration());
+        assertEquals(-1, new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100).getDuration());
+        assertEquals(-1, new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_SPIN, 1, 0).getDuration());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_returnsTrue() {
+        assertTrue(new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_NOOP, 1, 10).isHapticFeedbackCandidate());
+        assertTrue(new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 10).isHapticFeedbackCandidate());
+        assertTrue(new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10).isHapticFeedbackCandidate());
+        assertTrue(new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_THUD, 1, 10).isHapticFeedbackCandidate());
+        assertTrue(new PrimitiveSegment(
+                VibrationEffect.Composition.PRIMITIVE_SPIN, 1, 10).isHapticFeedbackCandidate());
+    }
 }
diff --git a/core/tests/coretests/src/android/os/vibrator/RampSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/RampSegmentTest.java
index 174b4a7..5f80d2a 100644
--- a/core/tests/coretests/src/android/os/vibrator/RampSegmentTest.java
+++ b/core/tests/coretests/src/android/os/vibrator/RampSegmentTest.java
@@ -125,4 +125,16 @@
         assertEquals(0.35f, initial.scale(0.8f).getStartAmplitude(), TOLERANCE);
         assertEquals(0.5f, initial.scale(0.8f).scale(1.25f).getStartAmplitude(), TOLERANCE);
     }
+
+    @Test
+    public void testDuration() {
+        assertEquals(10, new RampSegment(0.5f, 1, 0, 0, 10).getDuration());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_returnsTrue() {
+        // A single ramp segment duration is not checked here, but contributes to the effect known
+        // duration checked in VibrationEffect implementations.
+        assertTrue(new RampSegment(0.5f, 1, 0, 0, 5_000).isHapticFeedbackCandidate());
+    }
 }
diff --git a/core/tests/coretests/src/android/os/vibrator/StepSegmentTest.java b/core/tests/coretests/src/android/os/vibrator/StepSegmentTest.java
index 79529b8..fdce86a 100644
--- a/core/tests/coretests/src/android/os/vibrator/StepSegmentTest.java
+++ b/core/tests/coretests/src/android/os/vibrator/StepSegmentTest.java
@@ -141,4 +141,16 @@
         assertEquals(VibrationEffect.DEFAULT_AMPLITUDE, initial.scale(1.5f).getAmplitude(),
                 TOLERANCE);
     }
+
+    @Test
+    public void testDuration() {
+        assertEquals(5, new StepSegment(0, 0, 5).getDuration());
+    }
+
+    @Test
+    public void testIsHapticFeedbackCandidate_returnsTrue() {
+        // A single step segment duration is not checked here, but contributes to the effect known
+        // duration checked in VibrationEffect implementations.
+        assertTrue(new StepSegment(0, 0, 5_000).isHapticFeedbackCandidate());
+    }
 }
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index df5b3f5..a34d0ab 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -287,7 +287,7 @@
          *
          * @param computeHyphenation true if you want to use automatic hyphenations.
          */
-        public @NonNull Builder setComputeHyphenation(boolean computeHyphenation) {
+        public @NonNull @Deprecated Builder setComputeHyphenation(boolean computeHyphenation) {
             setComputeHyphenation(
                     computeHyphenation ? HYPHENATION_MODE_NORMAL : HYPHENATION_MODE_NONE);
             return this;
@@ -331,8 +331,6 @@
          *
          * {@link #HYPHENATION_MODE_NONE} is by default.
          *
-         * @see #setComputeHyphenation(boolean)
-         *
          * @param mode a hyphenation mode.
          */
         public @NonNull Builder setComputeHyphenation(@HyphenationMode int mode) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 7f37036..8e98b82 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -216,6 +216,14 @@
         }
     }
 
+    @Override
+    public void unregisterOrganizer() {
+        super.unregisterOrganizer();
+        if (mStartingWindow != null) {
+            mStartingWindow.clearAllWindows();
+        }
+    }
+
     public void createRootTask(int displayId, int windowingMode, TaskListener listener) {
         ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s",
                 displayId, windowingMode, listener.toString());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index c2ebc30..854fc60e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -1255,11 +1255,7 @@
         } else if (isOutPipDirection(direction)) {
             // If we are animating to fullscreen or split screen, then we need to reset the
             // override bounds on the task to ensure that the task "matches" the parent's bounds.
-            if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
-                taskBounds = destinationBounds;
-            } else {
-                taskBounds = null;
-            }
+            taskBounds = null;
             applyWindowingModeChangeOnExit(wct, direction);
         } else {
             // Just a resize in PIP
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 6280f76..a5579ae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -781,6 +781,7 @@
             final WindowContainerTransaction wct = new WindowContainerTransaction();
             // Make the stages adjacent to each other so they occlude what's behind them.
             wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
+            wct.setLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token);
             mTaskOrganizer.applyTransaction(wct);
         }
     }
@@ -788,6 +789,7 @@
     private void onStageRootTaskVanished(StageListenerImpl stageListener) {
         if (stageListener == mMainStageListener || stageListener == mSideStageListener) {
             final WindowContainerTransaction wct = new WindowContainerTransaction();
+            wct.clearLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token);
             // Deactivate the main stage if it no longer has a root task.
             mMainStage.deactivate(wct);
             mTaskOrganizer.applyTransaction(wct);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index a9c81b3..73f65b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -134,7 +134,8 @@
         mDisplayManager.getDisplay(DEFAULT_DISPLAY);
     }
 
-    private final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>();
+    @VisibleForTesting
+    final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>();
 
     /**
      * Records of {@link SurfaceControlViewHost} where the splash screen icon animation is
@@ -459,8 +460,23 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                 "Task start finish, remove starting surface for task: %d",
                 removalInfo.taskId);
-        removeWindowSynced(removalInfo);
+        removeWindowSynced(removalInfo, false /* immediately */);
+    }
 
+    /**
+     * Clear all starting windows immediately.
+     */
+    public void clearAllWindows() {
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
+                "Clear all starting windows immediately");
+        final int taskSize = mStartingWindowRecords.size();
+        final int[] taskIds = new int[taskSize];
+        for (int i = taskSize - 1; i >= 0; --i) {
+            taskIds[i] = mStartingWindowRecords.keyAt(i);
+        }
+        for (int i = taskSize - 1; i >= 0; --i) {
+            removeWindowNoAnimate(taskIds[i]);
+        }
     }
 
     /**
@@ -542,7 +558,8 @@
         return shouldSaveView;
     }
 
-    private void saveSplashScreenRecord(IBinder appToken, int taskId, View view,
+    @VisibleForTesting
+    void saveSplashScreenRecord(IBinder appToken, int taskId, View view,
             @StartingWindowType int suggestType) {
         final StartingWindowRecord tView = new StartingWindowRecord(appToken, view,
                 null/* TaskSnapshotWindow */, suggestType);
@@ -551,19 +568,18 @@
 
     private void removeWindowNoAnimate(int taskId) {
         mTmpRemovalInfo.taskId = taskId;
-        removeWindowSynced(mTmpRemovalInfo);
+        removeWindowSynced(mTmpRemovalInfo, true /* immediately */);
     }
 
     void onImeDrawnOnTask(int taskId) {
         final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
         if (record != null && record.mTaskSnapshotWindow != null
                 && record.mTaskSnapshotWindow.hasImeSurface()) {
-            record.mTaskSnapshotWindow.removeImmediately();
+            removeWindowNoAnimate(taskId);
         }
-        mStartingWindowRecords.remove(taskId);
     }
 
-    protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo) {
+    protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo, boolean immediately) {
         final int taskId = removalInfo.taskId;
         final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
         if (record != null) {
@@ -571,7 +587,8 @@
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                         "Removing splash screen window for task: %d", taskId);
                 if (record.mContentView != null) {
-                    if (record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
+                    if (immediately
+                            || record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
                         removeWindowInner(record.mDecorView, false);
                     } else {
                         if (removalInfo.playRevealAnimation) {
@@ -594,8 +611,12 @@
             if (record.mTaskSnapshotWindow != null) {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                         "Removing task snapshot window for %d", taskId);
-                record.mTaskSnapshotWindow.scheduleRemove(
-                        () -> mStartingWindowRecords.remove(taskId), removalInfo.deferRemoveForIme);
+                if (immediately) {
+                    record.mTaskSnapshotWindow.removeImmediately();
+                } else {
+                    record.mTaskSnapshotWindow.scheduleRemove(() ->
+                            mStartingWindowRecords.remove(taskId), removalInfo.deferRemoveForIme);
+                }
             }
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index b62360e..487eb70 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -194,6 +194,18 @@
     }
 
     /**
+     * Clear all starting window immediately, called this method when releasing the task organizer.
+     */
+    public void clearAllWindows() {
+        mSplashScreenExecutor.execute(() -> {
+            mStartingSurfaceDrawer.clearAllWindows();
+            synchronized (mTaskBackgroundColors) {
+                mTaskBackgroundColors.clear();
+            }
+        });
+    }
+
+    /**
      * The interface for calls from outside the Shell, within the host process.
      */
     private class StartingSurfaceImpl implements StartingSurface {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 70b7c67..d92b12e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -31,6 +31,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -117,16 +118,19 @@
                 WindowManager.LayoutParams params, int suggestType) {
             // listen for addView
             mAddWindowForTask = taskId;
+            saveSplashScreenRecord(appToken, taskId, view, suggestType);
             // Do not wait for background color
             return false;
         }
 
         @Override
-        protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo) {
+        protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo,
+                boolean immediately) {
             // listen for removeView
             if (mAddWindowForTask == removalInfo.taskId) {
                 mAddWindowForTask = 0;
             }
+            mStartingWindowRecords.remove(removalInfo.taskId);
         }
     }
 
@@ -179,7 +183,7 @@
         removalInfo.taskId = windowInfo.taskInfo.taskId;
         mStartingSurfaceDrawer.removeStartingWindow(removalInfo);
         waitHandlerIdle(mTestHandler);
-        verify(mStartingSurfaceDrawer).removeWindowSynced(any());
+        verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(false));
         assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, 0);
     }
 
@@ -267,11 +271,32 @@
 
             // Verify the task snapshot with IME snapshot will be removed when received the real IME
             // drawn callback.
+            // makeTaskSnapshotWindow shall call removeWindowSynced before there add a new
+            // StartingWindowRecord for the task.
             mStartingSurfaceDrawer.onImeDrawnOnTask(1);
-            verify(mockSnapshotWindow).removeImmediately();
+            verify(mStartingSurfaceDrawer, times(2))
+                    .removeWindowSynced(any(), eq(true));
         }
     }
 
+    @Test
+    public void testClearAllWindows() {
+        final int taskId = 1;
+        final StartingWindowInfo windowInfo =
+                createWindowInfo(taskId, android.R.style.Theme);
+        mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, mBinder,
+                STARTING_WINDOW_TYPE_SPLASH_SCREEN);
+        waitHandlerIdle(mTestHandler);
+        verify(mStartingSurfaceDrawer).addWindow(eq(taskId), eq(mBinder), any(), any(), any(),
+                eq(STARTING_WINDOW_TYPE_SPLASH_SCREEN));
+        assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, taskId);
+
+        mStartingSurfaceDrawer.clearAllWindows();
+        waitHandlerIdle(mTestHandler);
+        verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(true));
+        assertEquals(mStartingSurfaceDrawer.mStartingWindowRecords.size(), 0);
+    }
+
     private StartingWindowInfo createWindowInfo(int taskId, int themeResId) {
         StartingWindowInfo windowInfo = new StartingWindowInfo();
         final ActivityInfo info = new ActivityInfo();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java
index b8ad321..0b436a9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.bluetooth;
 
+import android.annotation.SuppressLint;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothUuid;
@@ -118,8 +119,8 @@
                     return true;
                 }
             } else if (btClass != null) {
-                if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP) ||
-                        btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
+                if (doesClassMatch(btClass, BluetoothClass.PROFILE_A2DP)
+                        || doesClassMatch(btClass, BluetoothClass.PROFILE_HEADSET)) {
                     return true;
                 }
             }
@@ -137,7 +138,7 @@
                 }
             }
             return btClass != null
-                    && btClass.doesClassMatch(BluetoothClass.PROFILE_OPP);
+                    && doesClassMatch(btClass, BluetoothClass.PROFILE_OPP);
         }
     }
 
@@ -151,7 +152,7 @@
                 }
             }
             return btClass != null
-                    && btClass.doesClassMatch(BluetoothClass.PROFILE_PANU);
+                    && doesClassMatch(btClass, BluetoothClass.PROFILE_PANU);
         }
     }
 
@@ -165,7 +166,12 @@
                 }
             }
             return btClass != null
-                    && btClass.doesClassMatch(BluetoothClass.PROFILE_NAP);
+                    && doesClassMatch(btClass, BluetoothClass.PROFILE_NAP);
         }
     }
+
+    @SuppressLint("NewApi") // Hidden API made public
+    private static boolean doesClassMatch(BluetoothClass btClass, int classId) {
+        return btClass.doesClassMatch(classId);
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 253629c..c9af4d5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -2,6 +2,7 @@
 
 import static com.android.settingslib.widget.AdaptiveOutlineDrawable.ICON_TYPE_ADVANCED;
 
+import android.annotation.SuppressLint;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
@@ -70,6 +71,12 @@
         void onShowError(Context context, String name, int messageResId);
     }
 
+    /**
+     * @param context to access resources from
+     * @param cachedDevice to get class from
+     * @return pair containing the drawable and the description of the Bluetooth class
+     *         of the device.
+     */
     public static Pair<Drawable, String> getBtClassDrawableWithDescription(Context context,
             CachedBluetoothDevice cachedDevice) {
         BluetoothClass btClass = cachedDevice.getBtClass();
@@ -110,13 +117,13 @@
             }
         }
         if (btClass != null) {
-            if (btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
+            if (doesClassMatch(btClass, BluetoothClass.PROFILE_HEADSET)) {
                 return new Pair<>(
                         getBluetoothDrawable(context,
                                 com.android.internal.R.drawable.ic_bt_headset_hfp),
                         context.getString(R.string.bluetooth_talkback_headset));
             }
-            if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
+            if (doesClassMatch(btClass, BluetoothClass.PROFILE_A2DP)) {
                 return new Pair<>(
                         getBluetoothDrawable(context,
                                 com.android.internal.R.drawable.ic_bt_headphones_a2dp),
@@ -376,4 +383,9 @@
         }
         return Uri.parse(data);
     }
+
+    @SuppressLint("NewApi") // Hidden API made public
+    private static boolean doesClassMatch(BluetoothClass btClass, int classId) {
+        return btClass.doesClassMatch(classId);
+    }
 }
diff --git a/packages/SystemUI/res/drawable/ic_list.xml b/packages/SystemUI/res/drawable/ic_list.xml
new file mode 100644
index 0000000..7ef5299
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_list.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2021 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<!-- Remove when Fgs manager tile is removed -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:pathData="M2,4h4v4h-4z"
+        android:fillColor="#000000"/>
+    <path
+        android:pathData="M8,4h14v4h-14z"
+        android:fillColor="#000000"/>
+    <path
+        android:pathData="M2,10h4v4h-4z"
+        android:fillColor="#000000"/>
+    <path
+        android:pathData="M8,10h14v4h-14z"
+        android:fillColor="#000000"/>
+    <path
+        android:pathData="M2,16h4v4h-4z"
+        android:fillColor="#000000"/>
+    <path
+        android:pathData="M8,16h14v4h-14z"
+        android:fillColor="#000000"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/fgs_manager_app_item.xml b/packages/SystemUI/res/layout/fgs_manager_app_item.xml
new file mode 100644
index 0000000..d034f4e
--- /dev/null
+++ b/packages/SystemUI/res/layout/fgs_manager_app_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2021 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginBottom="32dp"
+    android:orientation="horizontal"
+    android:gravity="center">
+
+  <ImageView
+      android:id="@+id/fgs_manager_app_item_icon"
+      android:layout_width="28dp"
+      android:layout_height="28dp"
+      android:layout_marginRight="12dp" />
+
+  <LinearLayout
+      android:layout_width="0dp"
+      android:layout_weight="1"
+      android:layout_height="wrap_content"
+      android:orientation="vertical">
+    <TextView
+        android:id="@+id/fgs_manager_app_item_label"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="start"
+        style="@style/TextAppearance.Dialog.Body" />
+    <TextView
+        android:id="@+id/fgs_manager_app_item_duration"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="start"
+        style="@style/FgsManagerAppDuration" />
+  </LinearLayout>
+
+  <Button
+      android:id="@+id/fgs_manager_app_item_stop_button"
+      android:layout_width="wrap_content"
+      android:layout_height="48dp"
+      android:text="@string/fgs_manager_app_item_stop_button_label"
+      android:layout_marginLeft="12dp"
+      style="?android:attr/buttonBarNeutralButtonStyle" />
+</LinearLayout>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 1bf2cd8..8b59d86 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -82,7 +82,7 @@
 
     <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
     <string name="quick_settings_tiles_stock" translatable="false">
-        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded
+        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,fgsmanager
     </string>
 
     <!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f608420..a437ae6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1295,4 +1295,6 @@
     <!-- ************************************************************************* -->
 
     <dimen name="keyguard_unfold_translation_x">16dp</dimen>
+
+    <dimen name="fgs_manager_min_width_minor">100%</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 111e3c42..300cb2d3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2358,4 +2358,9 @@
 
     <!-- Title for User Switch dialog. [CHAR LIMIT=20] -->
     <string name="qs_user_switch_dialog_title">Select user</string>
+
+    <!-- Title for dialog listing applications currently running in the backing [CHAR LIMIT=NONE]-->
+    <string name="fgs_manager_dialog_title">Apps running in the background</string>
+    <!-- Label of the button to stop the app from running in the background [CHAR LIMIT=12]-->
+    <string name="fgs_manager_app_item_stop_button_label">Stop</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 061a748..12a022d 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -853,7 +853,6 @@
     <style name="Widget.SliceView.Panel">
         <item name="titleSize">16sp</item>
         <item name="rowStyle">@style/SliceRow</item>
-        <item name="android:background">?android:attr/colorBackgroundFloating</item>
     </style>
 
     <style name="SliceRow">
@@ -990,4 +989,14 @@
 
     <style name="InternetDialog.Divider.Active"/>
 
+    <style name="FgsManagerDialogTitle">
+        <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:textDirection">locale</item>
+    </style>
+
+    <style name="FgsManagerAppDuration">
+        <item name="android:fontFamily">?android:attr/textAppearanceSmall</item>
+        <item name="android:textDirection">locale</item>
+    </style>
 </resources>
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
index ed29bc7..5fdb497 100644
--- a/packages/SystemUI/res/values/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -298,4 +298,14 @@
         <item>Off</item>
         <item>On</item>
     </string-array>
+
+    <!-- State names for fgsmanager tile: unavailable, off, on.
+         This subtitle is shown when the tile is in that particular state but does not set its own
+         subtitle, so some of these may never appear on screen. They should still be translated as
+         if they could appear.[CHAR LIMIT=32] -->
+    <string-array name="tile_states_fgsmanager">
+        <item>Unavailable</item>
+        <item>Off</item>
+        <item>On</item>
+    </string-array>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java b/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java
index c941d66..e4e0da6 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SecureSettingsContentObserver.java
@@ -71,7 +71,9 @@
     public void addListener(@NonNull T listener) {
         Objects.requireNonNull(listener, "listener must be non-null");
 
-        mListeners.add(listener);
+        if (!mListeners.contains(listener)) {
+            mListeners.add(listener);
+        }
 
         if (mListeners.size() == 1) {
             mContentResolver.registerContentObserver(
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
index cff6cf1..cc5a792 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
@@ -98,7 +98,8 @@
         mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
 
-        init();
+        mIsKeyguardVisible = false;
+        mIsAccessibilityManagerServiceReady = false;
     }
 
     /**
@@ -124,9 +125,8 @@
         handleFloatingMenuVisibility(mIsKeyguardVisible, mBtnMode, mBtnTargets);
     }
 
-    private void init() {
-        mIsKeyguardVisible = false;
-        mIsAccessibilityManagerServiceReady = false;
+    /** Initializes the AccessibilityFloatingMenuController configurations. */
+    public void init() {
         mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
         mBtnTargets = mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets();
         registerContentObservers();
diff --git a/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialog.kt b/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialog.kt
new file mode 100644
index 0000000..42f3512
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialog.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.fgsmanager
+
+import android.content.Context
+import android.os.Bundle
+import android.text.format.DateUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.annotation.GuardedBy
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.fgsmanager.FgsManagerDialogController.RunningApp
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.util.time.SystemClock
+import java.util.concurrent.Executor
+
+/**
+ * Dialog which shows a list of running foreground services and offers controls to them
+ */
+class FgsManagerDialog(
+    context: Context,
+    private val executor: Executor,
+    @Background private val backgroundExecutor: Executor,
+    private val systemClock: SystemClock,
+    private val fgsManagerDialogController: FgsManagerDialogController
+) : SystemUIDialog(context, R.style.Theme_SystemUI_Dialog) {
+
+    private val appListRecyclerView: RecyclerView = RecyclerView(this.context)
+    private val adapter: AppListAdapter = AppListAdapter()
+
+    init {
+        setTitle(R.string.fgs_manager_dialog_title)
+        setView(appListRecyclerView)
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        appListRecyclerView.layoutManager = LinearLayoutManager(context)
+        fgsManagerDialogController.registerDialogForChanges(
+                object : FgsManagerDialogController.FgsManagerDialogCallback {
+                    override fun onRunningAppsChanged(apps: List<RunningApp>) {
+                        executor.execute {
+                            adapter.setData(apps)
+                        }
+                    }
+                }
+        )
+        appListRecyclerView.adapter = adapter
+        backgroundExecutor.execute { adapter.setData(fgsManagerDialogController.runningAppList) }
+    }
+
+    private inner class AppListAdapter : RecyclerView.Adapter<AppItemViewHolder>() {
+        private val lock = Any()
+
+        @GuardedBy("lock")
+        private val data: MutableList<RunningApp> = ArrayList()
+        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppItemViewHolder {
+            return AppItemViewHolder(LayoutInflater.from(context)
+                            .inflate(R.layout.fgs_manager_app_item, parent, false))
+        }
+
+        override fun onBindViewHolder(holder: AppItemViewHolder, position: Int) {
+            var runningApp: RunningApp
+            synchronized(lock) {
+                runningApp = data[position]
+            }
+            with(holder) {
+                iconView.setImageDrawable(runningApp.mIcon)
+                appLabelView.text = runningApp.mAppLabel
+                durationView.text = DateUtils.formatDuration(
+                        Math.max(systemClock.elapsedRealtime() - runningApp.mTimeStarted, 60000),
+                        DateUtils.LENGTH_MEDIUM)
+                stopButton.setOnClickListener {
+                    fgsManagerDialogController
+                            .stopAllFgs(runningApp.mUserId, runningApp.mPackageName)
+                }
+            }
+        }
+
+        override fun getItemCount(): Int {
+            synchronized(lock) { return data.size }
+        }
+
+        fun setData(newData: List<RunningApp>) {
+            var oldData: List<RunningApp>
+            synchronized(lock) {
+                oldData = ArrayList(data)
+                data.clear()
+                data.addAll(newData)
+            }
+
+            DiffUtil.calculateDiff(object : DiffUtil.Callback() {
+                override fun getOldListSize(): Int {
+                    return oldData.size
+                }
+
+                override fun getNewListSize(): Int {
+                    return newData.size
+                }
+
+                override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int):
+                        Boolean {
+                    return oldData[oldItemPosition] == newData[newItemPosition]
+                }
+
+                override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int):
+                        Boolean {
+                    return true // TODO, look into updating the time subtext
+                }
+            }).dispatchUpdatesTo(this)
+        }
+    }
+
+    private class AppItemViewHolder(parent: View) : RecyclerView.ViewHolder(parent) {
+        val appLabelView: TextView = parent.requireViewById(R.id.fgs_manager_app_item_label)
+        val durationView: TextView = parent.requireViewById(R.id.fgs_manager_app_item_duration)
+        val iconView: ImageView = parent.requireViewById(R.id.fgs_manager_app_item_icon)
+        val stopButton: Button = parent.requireViewById(R.id.fgs_manager_app_item_stop_button)
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialogController.kt b/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialogController.kt
new file mode 100644
index 0000000..159ed39
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialogController.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.fgsmanager
+
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.NameNotFoundException
+import android.graphics.drawable.Drawable
+import android.os.Handler
+import android.os.UserHandle
+import android.util.ArrayMap
+import android.util.Log
+import androidx.annotation.GuardedBy
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.policy.RunningFgsController
+import com.android.systemui.statusbar.policy.RunningFgsController.UserPackageTime
+import javax.inject.Inject
+
+/**
+ * Controls events relevant to FgsManagerDialog
+ */
+class FgsManagerDialogController @Inject constructor(
+    private val packageManager: PackageManager,
+    @Background private val backgroundHandler: Handler,
+    private val runningFgsController: RunningFgsController
+) : RunningFgsController.Callback {
+    private val lock = Any()
+    private val clearCacheToken = Any()
+
+    @GuardedBy("lock")
+    private var runningApps: Map<UserPackageTime, RunningApp>? = null
+    @GuardedBy("lock")
+    private var listener: FgsManagerDialogCallback? = null
+
+    interface FgsManagerDialogCallback {
+        fun onRunningAppsChanged(apps: List<RunningApp>)
+    }
+
+    data class RunningApp(
+        val mUserId: Int,
+        val mPackageName: String,
+        val mAppLabel: CharSequence,
+        val mIcon: Drawable,
+        val mTimeStarted: Long
+    )
+
+    val runningAppList: List<RunningApp>
+        get() {
+            synchronized(lock) {
+                if (runningApps == null) {
+                    onFgsPackagesChangedLocked(runningFgsController.getPackagesWithFgs())
+                }
+                return convertToRunningAppList(runningApps!!)
+            }
+        }
+
+    fun registerDialogForChanges(callback: FgsManagerDialogCallback) {
+        synchronized(lock) {
+            runningFgsController.addCallback(this)
+            listener = callback
+            backgroundHandler.removeCallbacksAndMessages(clearCacheToken)
+        }
+    }
+
+    fun onFinishDialog() {
+        synchronized(lock) {
+            listener = null
+            // Keep data such as icons cached for some time since loading can be slow
+            backgroundHandler.postDelayed(
+                    {
+                        synchronized(lock) {
+                            runningFgsController.removeCallback(this)
+                            runningApps = null
+                        }
+                    }, clearCacheToken, RUNNING_APP_CACHE_TIMEOUT_MILLIS)
+        }
+    }
+
+    private fun onRunningAppsChanged(apps: ArrayMap<UserPackageTime, RunningApp>) {
+        listener?.let {
+            backgroundHandler.post { it.onRunningAppsChanged(convertToRunningAppList(apps)) }
+        }
+    }
+
+    override fun onFgsPackagesChanged(packages: List<UserPackageTime>) {
+        backgroundHandler.post {
+            synchronized(lock) { onFgsPackagesChangedLocked(packages) }
+        }
+    }
+
+    /**
+     * Run on background thread
+     */
+    private fun onFgsPackagesChangedLocked(packages: List<UserPackageTime>) {
+        val newRunningApps = ArrayMap<UserPackageTime, RunningApp>()
+        for (packageWithFgs in packages) {
+            val ra = runningApps?.get(packageWithFgs)
+            if (ra == null) {
+                val userId = packageWithFgs.userId
+                val packageName = packageWithFgs.packageName
+                try {
+                    val ai = packageManager.getApplicationInfo(packageName, 0)
+                    var icon = packageManager.getApplicationIcon(ai)
+                    icon = packageManager.getUserBadgedIcon(icon,
+                            UserHandle.of(userId))
+                    val label = packageManager.getApplicationLabel(ai)
+                    newRunningApps[packageWithFgs] = RunningApp(userId, packageName,
+                            label, icon, packageWithFgs.startTimeMillis)
+                } catch (e: NameNotFoundException) {
+                    Log.e(LOG_TAG,
+                            "Application info not found: $packageName", e)
+                }
+            } else {
+                newRunningApps[packageWithFgs] = ra
+            }
+        }
+        runningApps = newRunningApps
+        onRunningAppsChanged(newRunningApps)
+    }
+
+    fun stopAllFgs(userId: Int, packageName: String) {
+        runningFgsController.stopFgs(userId, packageName)
+    }
+
+    companion object {
+        private val LOG_TAG = FgsManagerDialogController::class.java.simpleName
+        private const val RUNNING_APP_CACHE_TIMEOUT_MILLIS: Long = 20_000
+
+        private fun convertToRunningAppList(apps: Map<UserPackageTime, RunningApp>):
+                List<RunningApp> {
+            val result = mutableListOf<RunningApp>()
+            result.addAll(apps.values)
+            result.sortWith { a: RunningApp, b: RunningApp ->
+                b.mTimeStarted.compareTo(a.mTimeStarted)
+            }
+            return result
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialogFactory.kt
new file mode 100644
index 0000000..2874929
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/fgsmanager/FgsManagerDialogFactory.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.fgsmanager
+
+import android.content.Context
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.animation.DialogLaunchAnimator
+import android.content.DialogInterface
+import android.view.View
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.util.time.SystemClock
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * Factory to create [FgsManagerDialog] instances
+ */
+@SysUISingleton
+class FgsManagerDialogFactory
+@Inject constructor(
+    private val context: Context,
+    @Main private val executor: Executor,
+    @Background private val backgroundExecutor: Executor,
+    private val systemClock: SystemClock,
+    private val dialogLaunchAnimator: DialogLaunchAnimator,
+    private val fgsManagerDialogController: FgsManagerDialogController
+) {
+
+    val lock = Any()
+
+    companion object {
+        private var fgsManagerDialog: FgsManagerDialog? = null
+    }
+
+    /**
+     * Creates the dialog if it doesn't exist
+     */
+    fun create(viewLaunchedFrom: View?) {
+        if (fgsManagerDialog == null) {
+            fgsManagerDialog = FgsManagerDialog(context, executor, backgroundExecutor,
+                    systemClock, fgsManagerDialogController)
+            fgsManagerDialog!!.setOnDismissListener { i: DialogInterface? ->
+                fgsManagerDialogController.onFinishDialog()
+                fgsManagerDialog = null
+            }
+            dialogLaunchAnimator.showFromView(fgsManagerDialog!!, viewLaunchedFrom!!)
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 6d1bbee..48255b5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -34,6 +34,8 @@
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.DeviceControlsController;
 import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.RunningFgsController;
+import com.android.systemui.statusbar.policy.RunningFgsControllerImpl;
 import com.android.systemui.statusbar.policy.WalletController;
 import com.android.systemui.util.settings.SecureSettings;
 
@@ -89,4 +91,9 @@
     /** */
     @Binds
     QSHost provideQsHost(QSTileHost controllerImpl);
+
+    /** */
+    @Binds
+    RunningFgsController provideRunningFgsController(
+            RunningFgsControllerImpl runningFgsController);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 16be998..ac95bf5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -36,6 +36,7 @@
 import com.android.systemui.qs.tiles.DataSaverTile;
 import com.android.systemui.qs.tiles.DeviceControlsTile;
 import com.android.systemui.qs.tiles.DndTile;
+import com.android.systemui.qs.tiles.FgsManagerTile;
 import com.android.systemui.qs.tiles.FlashlightTile;
 import com.android.systemui.qs.tiles.HotspotTile;
 import com.android.systemui.qs.tiles.InternetTile;
@@ -94,6 +95,7 @@
     private final Provider<QuickAccessWalletTile> mQuickAccessWalletTileProvider;
     private final Provider<QRCodeScannerTile> mQRCodeScannerTileProvider;
     private final Provider<OneHandedModeTile> mOneHandedModeTileProvider;
+    private final Provider<FgsManagerTile> mFgsManagerTileProvider;
 
     private final Lazy<QSHost> mQsHostLazy;
     private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -130,7 +132,8 @@
             Provider<AlarmTile> alarmTileProvider,
             Provider<QuickAccessWalletTile> quickAccessWalletTileProvider,
             Provider<QRCodeScannerTile> qrCodeScannerTileProvider,
-            Provider<OneHandedModeTile> oneHandedModeTileProvider) {
+            Provider<OneHandedModeTile> oneHandedModeTileProvider,
+            Provider<FgsManagerTile> fgsManagerTileProvider) {
         mQsHostLazy = qsHostLazy;
         mCustomTileBuilderProvider = customTileBuilderProvider;
 
@@ -163,6 +166,7 @@
         mQuickAccessWalletTileProvider = quickAccessWalletTileProvider;
         mQRCodeScannerTileProvider = qrCodeScannerTileProvider;
         mOneHandedModeTileProvider = oneHandedModeTileProvider;
+        mFgsManagerTileProvider = fgsManagerTileProvider;
     }
 
     public QSTile createTile(String tileSpec) {
@@ -233,6 +237,8 @@
                 return mQRCodeScannerTileProvider.get();
             case "onehanded":
                 return mOneHandedModeTileProvider.get();
+            case "fgsmanager":
+                return mFgsManagerTileProvider.get();
         }
 
         // Custom tiles
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 09fad30..eb74b1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -652,7 +652,8 @@
         "wallet" to R.array.tile_states_wallet,
         "qr_code_scanner" to R.array.tile_states_qr_code_scanner,
         "alarm" to R.array.tile_states_alarm,
-        "onehanded" to R.array.tile_states_onehanded
+        "onehanded" to R.array.tile_states_onehanded,
+        "fgsmanager" to R.array.tile_states_fgsmanager
     )
 
     fun getSubtitleId(spec: String?): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FgsManagerTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FgsManagerTile.kt
new file mode 100644
index 0000000..75cf4d1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FgsManagerTile.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.qs.tiles
+
+import android.content.Intent
+import android.os.Handler
+import android.os.Looper
+import android.provider.DeviceConfig
+import android.view.View
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+import com.android.internal.logging.MetricsLogger
+import com.android.systemui.DejankUtils
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.fgsmanager.FgsManagerDialogFactory
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.RunningFgsController
+import com.android.systemui.statusbar.policy.RunningFgsController.UserPackageTime
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * Quicksettings tile for the foreground services manager (task manager)
+ */
+class FgsManagerTile @Inject constructor(
+    host: QSHost?,
+    @Background backgroundLooper: Looper?,
+    @Background private val backgroundExecutor: Executor?,
+    @Main mainHandler: Handler?,
+    falsingManager: FalsingManager?,
+    metricsLogger: MetricsLogger?,
+    statusBarStateController: StatusBarStateController?,
+    activityStarter: ActivityStarter?,
+    qsLogger: QSLogger?,
+    private val fgsManagerDialogFactory: FgsManagerDialogFactory,
+    private val runningFgsController: RunningFgsController
+) : QSTileImpl<QSTile.State?>(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
+        statusBarStateController, activityStarter, qsLogger), RunningFgsController.Callback {
+
+    override fun handleInitialize() {
+        super.handleInitialize()
+        mUiHandler.post { runningFgsController.observe(lifecycle, this) }
+    }
+
+    override fun isAvailable(): Boolean {
+        return DejankUtils.whitelistIpcs<Boolean> {
+            DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                    SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED, false)
+        }
+    }
+
+    override fun newTileState(): QSTile.State {
+        return QSTile.State()
+    }
+
+    override fun handleClick(view: View?) {
+        mUiHandler.post { fgsManagerDialogFactory.create(view) }
+    }
+
+    override fun handleUpdateState(state: QSTile.State?, arg: Any?) {
+        state?.label = tileLabel
+        state?.secondaryLabel = runningFgsController.getPackagesWithFgs().size.toString()
+        state?.handlesLongClick = false
+        state?.icon = ResourceIcon.get(R.drawable.ic_list)
+    }
+
+    override fun getMetricsCategory(): Int = 0
+
+    override fun getLongClickIntent(): Intent? = null
+
+    // Inline the string so we don't waste translator time since this isn't used in the mocks.
+    // TODO If mocks change need to remember to move this to strings.xml
+    override fun getTileLabel(): CharSequence = "Active apps"
+
+    override fun onFgsPackagesChanged(packages: List<UserPackageTime>) = refreshState()
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index 6bba1ed..033fe1e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -391,6 +391,8 @@
             array.recycle();
 
             mMobileDataToggle.setVisibility(mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
+            mMobileToggleDivider.setVisibility(
+                    mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 1aeab22..84ef079 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -134,6 +134,7 @@
 import com.android.systemui.InitController;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
+import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DelegateLaunchAnimatorController;
 import com.android.systemui.assist.AssistManager;
@@ -736,6 +737,7 @@
             VisualStabilityManager visualStabilityManager,
             DeviceProvisionedController deviceProvisionedController,
             NavigationBarController navigationBarController,
+            AccessibilityFloatingMenuController accessibilityFloatingMenuController,
             Lazy<AssistManager> assistManagerLazy,
             ConfigurationController configurationController,
             NotificationShadeWindowController notificationShadeWindowController,
@@ -839,6 +841,7 @@
         mVisualStabilityManager = visualStabilityManager;
         mDeviceProvisionedController = deviceProvisionedController;
         mNavigationBarController = navigationBarController;
+        mAccessibilityFloatingMenuController = accessibilityFloatingMenuController;
         mAssistManagerLazy = assistManagerLazy;
         mConfigurationController = configurationController;
         mNotificationShadeWindowController = notificationShadeWindowController;
@@ -1054,6 +1057,8 @@
         mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback);
         mLifecycle.setCurrentState(RESUMED);
 
+        mAccessibilityFloatingMenuController.init();
+
         // set the initial view visibility
         int disabledFlags1 = result.mDisabledFlags1;
         int disabledFlags2 = result.mDisabledFlags2;
@@ -3813,6 +3818,7 @@
     private final DeviceProvisionedController mDeviceProvisionedController;
 
     private final NavigationBarController mNavigationBarController;
+    private final AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
 
     // UI-specific methods
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 24b7b7f..33171b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -28,6 +28,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.InitController;
+import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -185,6 +186,7 @@
             VisualStabilityManager visualStabilityManager,
             DeviceProvisionedController deviceProvisionedController,
             NavigationBarController navigationBarController,
+            AccessibilityFloatingMenuController accessibilityFloatingMenuController,
             Lazy<AssistManager> assistManagerLazy,
             ConfigurationController configurationController,
             NotificationShadeWindowController notificationShadeWindowController,
@@ -287,6 +289,7 @@
                 visualStabilityManager,
                 deviceProvisionedController,
                 navigationBarController,
+                accessibilityFloatingMenuController,
                 assistManagerLazy,
                 configurationController,
                 notificationShadeWindowController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RunningFgsController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RunningFgsController.kt
new file mode 100644
index 0000000..c6dbdb1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RunningFgsController.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.policy
+
+/**
+ * Interface for tracking packages with running foreground services and demoting foreground status
+ */
+interface RunningFgsController : CallbackController<RunningFgsController.Callback> {
+
+    /**
+     * @return A list of [UserPackageTime]s which have running foreground service(s)
+     */
+    fun getPackagesWithFgs(): List<UserPackageTime>
+
+    /**
+     * Stops all foreground services running as a package
+     * @param userId the userId the package is running under
+     * @param packageName the packageName
+     */
+    fun stopFgs(userId: Int, packageName: String)
+
+    /**
+     * Returns when the list of packages with foreground services changes
+     */
+    interface Callback {
+        /**
+         * The thing that
+         * @param packages the list of packages
+         */
+        fun onFgsPackagesChanged(packages: List<UserPackageTime>)
+    }
+
+    /**
+     * A triplet <user, packageName, timeMillis> where each element is a package running
+     * under a user that has had at least one foreground service running since timeMillis.
+     * Time should be derived from [SystemClock.elapsedRealtime].
+     */
+    data class UserPackageTime(val userId: Int, val packageName: String, val startTimeMillis: Long)
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RunningFgsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RunningFgsControllerImpl.kt
new file mode 100644
index 0000000..d44d365
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RunningFgsControllerImpl.kt
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.policy
+
+import android.app.IActivityManager
+import android.app.IForegroundServiceObserver
+import android.os.IBinder
+import android.os.RemoteException
+import android.util.Log
+import androidx.annotation.GuardedBy
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.policy.RunningFgsController.Callback
+import com.android.systemui.statusbar.policy.RunningFgsController.UserPackageTime
+import com.android.systemui.util.time.SystemClock
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * Implementation for [RunningFgsController]
+ */
+@SysUISingleton
+class RunningFgsControllerImpl @Inject constructor(
+    @Background private val executor: Executor,
+    private val systemClock: SystemClock,
+    private val activityManager: IActivityManager
+) : RunningFgsController, IForegroundServiceObserver.Stub() {
+
+    companion object {
+        private val LOG_TAG = RunningFgsControllerImpl::class.java.simpleName
+    }
+
+    private val lock = Any()
+
+    @GuardedBy("lock")
+    var initialized = false
+
+    @GuardedBy("lock")
+    private val runningServiceTokens = mutableMapOf<UserPackageKey, StartTimeAndTokensValue>()
+
+    @GuardedBy("lock")
+    private val callbacks = mutableSetOf<Callback>()
+
+    fun init() {
+        synchronized(lock) {
+            if (initialized) {
+                return
+            }
+            try {
+                activityManager.registerForegroundServiceObserver(this)
+            } catch (e: RemoteException) {
+                e.rethrowFromSystemServer()
+            }
+
+            initialized = true
+        }
+    }
+
+    override fun addCallback(listener: Callback) {
+        init()
+        synchronized(lock) { callbacks.add(listener) }
+    }
+
+    override fun removeCallback(listener: Callback) {
+        init()
+        synchronized(lock) {
+            if (!callbacks.remove(listener)) {
+                Log.e(LOG_TAG, "Callback was not registered.", RuntimeException())
+            }
+        }
+    }
+
+    override fun observe(lifecycle: Lifecycle?, listener: Callback?): Callback {
+        init()
+        return super.observe(lifecycle, listener)
+    }
+
+    override fun observe(owner: LifecycleOwner?, listener: Callback?): Callback {
+        init()
+        return super.observe(owner, listener)
+    }
+
+    override fun getPackagesWithFgs(): List<UserPackageTime> {
+        init()
+        return synchronized(lock) { getPackagesWithFgsLocked() }
+    }
+
+    private fun getPackagesWithFgsLocked(): List<UserPackageTime> =
+            runningServiceTokens.map {
+                UserPackageTime(it.key.userId, it.key.packageName, it.value.fgsStartTime)
+            }
+
+    override fun stopFgs(userId: Int, packageName: String) {
+        init()
+        try {
+            activityManager.makeServicesNonForeground(packageName, userId)
+        } catch (e: RemoteException) {
+            e.rethrowFromSystemServer()
+        }
+    }
+
+    private data class UserPackageKey(
+        val userId: Int,
+        val packageName: String
+    )
+
+    private class StartTimeAndTokensValue(systemClock: SystemClock) {
+        val fgsStartTime = systemClock.elapsedRealtime()
+        var tokens = mutableSetOf<IBinder>()
+        fun addToken(token: IBinder): Boolean {
+            return tokens.add(token)
+        }
+
+        fun removeToken(token: IBinder): Boolean {
+            return tokens.remove(token)
+        }
+
+        val isEmpty: Boolean
+            get() = tokens.isEmpty()
+    }
+
+    override fun onForegroundStateChanged(
+        token: IBinder,
+        packageName: String,
+        userId: Int,
+        isForeground: Boolean
+    ) {
+        val result = synchronized(lock) {
+            val userPackageKey = UserPackageKey(userId, packageName)
+            if (isForeground) {
+                var addedNew = false
+                runningServiceTokens.getOrPut(userPackageKey) {
+                    addedNew = true
+                    StartTimeAndTokensValue(systemClock)
+                }.addToken(token)
+                if (!addedNew) {
+                    return
+                }
+            } else {
+                val startTimeAndTokensValue = runningServiceTokens[userPackageKey]
+                if (startTimeAndTokensValue?.removeToken(token) == false) {
+                    Log.e(LOG_TAG,
+                            "Stopped foreground service was not known to be running.")
+                    return
+                }
+                if (!startTimeAndTokensValue!!.isEmpty) {
+                    return
+                }
+                runningServiceTokens.remove(userPackageKey)
+            }
+            getPackagesWithFgsLocked().toList()
+        }
+
+        callbacks.forEach { executor.execute { it.onFgsPackagesChanged(result) } }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 7a664b0..a537b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -219,6 +219,7 @@
     private void clearLayoutLineCount(View view) {
         if (view instanceof TextView) {
             ((TextView) view).nullLayouts();
+            view.forceLayout();
         }
     }
 
@@ -271,6 +272,9 @@
 
             clearLayoutLineCount(child);
             child.measure(MEASURE_SPEC_ANY_LENGTH, heightMeasureSpec);
+            if (((Button) child).getLayout() == null) {
+                Log.wtf(TAG, "Button layout is null after measure.");
+            }
 
             coveredSuggestions.add(child);
 
@@ -604,6 +608,9 @@
                 button.getPaddingLeft() + button.getPaddingRight() + textWidth
                       + getLeftCompoundDrawableWidthWithPadding(button), MeasureSpec.AT_MOST);
         button.measure(widthMeasureSpec, heightMeasureSpec);
+        if (button.getLayout() == null) {
+            Log.wtf(TAG, "Button layout is null after measure.");
+        }
 
         final int newWidth = button.getMeasuredWidth();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
index cdf40a1..8ca17b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
@@ -291,9 +291,12 @@
         mTargetsObserver = spy(Dependency.get(AccessibilityButtonTargetsObserver.class));
         mModeObserver = spy(Dependency.get(AccessibilityButtonModeObserver.class));
         mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+        final AccessibilityFloatingMenuController controller =
+                new AccessibilityFloatingMenuController(mContextWrapper, mTargetsObserver,
+                        mModeObserver, mKeyguardUpdateMonitor);
+        controller.init();
 
-        return new AccessibilityFloatingMenuController(mContextWrapper, mTargetsObserver,
-                mModeObserver, mKeyguardUpdateMonitor);
+        return controller;
     }
 
     private void enableAccessibilityFloatingMenuConfig() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 6625d73..a34d2f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -77,6 +77,7 @@
 import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -219,6 +220,7 @@
     @Mock private NotificationGutsManager mNotificationGutsManager;
     @Mock private NotificationMediaManager mNotificationMediaManager;
     @Mock private NavigationBarController mNavigationBarController;
+    @Mock private AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
     @Mock private BypassHeadsUpNotifier mBypassHeadsUpNotifier;
     @Mock private SysuiColorExtractor mColorExtractor;
     @Mock private ColorExtractor.GradientColors mGradientColors;
@@ -416,6 +418,7 @@
                 mVisualStabilityManager,
                 mDeviceProvisionedController,
                 mNavigationBarController,
+                mAccessibilityFloatingMenuController,
                 () -> mAssistManager,
                 configurationController,
                 mNotificationShadeWindowController,
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 6ac015b..f3fad84 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -18,6 +18,7 @@
 
 import android.annotation.AppIdInt;
 import android.annotation.IntDef;
+import android.annotation.LongDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -108,7 +109,7 @@
     // Please note the numbers should be continuous.
     public static final int LAST_KNOWN_PACKAGE = PACKAGE_RECENTS;
 
-    @IntDef(flag = true, prefix = "RESOLVE_", value = {
+    @LongDef(flag = true, prefix = "RESOLVE_", value = {
             RESOLVE_NON_BROWSER_ONLY,
             RESOLVE_NON_RESOLVER_ONLY
     })
@@ -197,7 +198,7 @@
      * @see PackageManager#getPackageInfo(String, int)
      */
     public abstract PackageInfo getPackageInfo(String packageName,
-            @PackageInfoFlags int flags, int filterCallingUid, int userId);
+            @PackageInfoFlags long flags, int filterCallingUid, int userId);
 
     /**
      * Retrieve CE data directory inode number of an application.
@@ -226,7 +227,7 @@
      *         deleted with {@code DELETE_KEEP_DATA} flag set).
      */
     public abstract List<ApplicationInfo> getInstalledApplications(
-            @ApplicationInfoFlags int flags, @UserIdInt int userId, int callingUid);
+            @ApplicationInfoFlags long flags, @UserIdInt int userId, int callingUid);
 
     /**
      * Retrieve launcher extras for a suspended package provided to the system in
@@ -323,7 +324,7 @@
      * @see PackageManager#getPackageUidAsUser(String, int, int)
      * @return The app's uid, or < 0 if the package was not found in that user
      */
-    public abstract int getPackageUid(String packageName, @PackageInfoFlags int flags, int userId);
+    public abstract int getPackageUid(String packageName, @PackageInfoFlags long flags, int userId);
 
     /**
      * Retrieve all of the information we know about a particular package/application.
@@ -332,7 +333,7 @@
      * @see PackageManager#getApplicationInfo(String, int)
      */
     public abstract ApplicationInfo getApplicationInfo(String packageName,
-            @ApplicationInfoFlags int flags, int filterCallingUid, int userId);
+            @ApplicationInfoFlags long flags, int filterCallingUid, int userId);
 
     /**
      * Retrieve all of the information we know about a particular activity class.
@@ -341,7 +342,7 @@
      * @see PackageManager#getActivityInfo(ComponentName, int)
      */
     public abstract ActivityInfo getActivityInfo(ComponentName component,
-            @ComponentInfoFlags int flags, int filterCallingUid, int userId);
+            @ComponentInfoFlags long flags, int filterCallingUid, int userId);
 
     /**
      * Retrieve all activities that can be performed for the given intent.
@@ -352,7 +353,7 @@
      * @see PackageManager#queryIntentActivities(Intent, int)
      */
     public abstract List<ResolveInfo> queryIntentActivities(
-            Intent intent, @Nullable String resolvedType, @ResolveInfoFlags int flags,
+            Intent intent, @Nullable String resolvedType, @ResolveInfoFlags long flags,
             int filterCallingUid, int userId);
 
 
@@ -360,14 +361,14 @@
      * Retrieve all receivers that can handle a broadcast of the given intent.
      */
     public abstract List<ResolveInfo> queryIntentReceivers(Intent intent,
-            String resolvedType, int flags, int filterCallingUid, int userId);
+            String resolvedType, @ResolveInfoFlags long flags, int filterCallingUid, int userId);
 
     /**
      * Retrieve all services that can be performed for the given intent.
      * @see PackageManager#queryIntentServices(Intent, int)
      */
     public abstract List<ResolveInfo> queryIntentServices(
-            Intent intent, int flags, int callingUid, int userId);
+            Intent intent, @ResolveInfoFlags long flags, int callingUid, int userId);
 
     /**
      * Interface to {@link com.android.server.pm.PackageManagerService#getHomeActivitiesAsUser}.
@@ -591,20 +592,20 @@
      * Resolves an activity intent, allowing instant apps to be resolved.
      */
     public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
-            int flags, @PrivateResolveFlags int privateResolveFlags, int userId,
+            @ResolveInfoFlags long flags, @PrivateResolveFlags long privateResolveFlags, int userId,
             boolean resolveForStart, int filterCallingUid);
 
     /**
     * Resolves a service intent, allowing instant apps to be resolved.
     */
     public abstract ResolveInfo resolveService(Intent intent, String resolvedType,
-           int flags, int userId, int callingUid);
+            @ResolveInfoFlags long flags, int userId, int callingUid);
 
     /**
     * Resolves a content provider intent.
     */
-    public abstract ProviderInfo resolveContentProvider(String name, int flags, int userId,
-            int callingUid);
+    public abstract ProviderInfo resolveContentProvider(String name, @ComponentInfoFlags long flags,
+            int userId, int callingUid);
 
     /**
      * Track the creator of a new isolated uid.
@@ -875,8 +876,8 @@
             throws IOException;
 
     /** Returns {@code true} if the specified component is enabled and matches the given flags. */
-    public abstract boolean isEnabledAndMatches(@NonNull ParsedMainComponent component, int flags,
-            int userId);
+    public abstract boolean isEnabledAndMatches(@NonNull ParsedMainComponent component,
+            @ComponentInfoFlags long flags, int userId);
 
     /** Returns {@code true} if the given user requires extra badging for icons. */
     public abstract boolean userNeedsBadging(int userId);
@@ -1024,7 +1025,7 @@
      * @param flags flags about the uninstall.
      */
     public abstract void uninstallApex(String packageName, long versionCode, int userId,
-            IntentSender intentSender, int flags);
+            IntentSender intentSender, @PackageManager.InstallFlags int installFlags);
 
     /**
      * Update fingerprint of build that updated the runtime permissions for a user.
@@ -1260,5 +1261,5 @@
     /**
      * Reconcile all app data for the given user.
      */
-    public abstract void reconcileAppsData(int userId, int flags, boolean migrateAppsData);
+    public abstract void reconcileAppsData(int userId, int storageFlags, boolean migrateAppsData);
 }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 1c62699..a36a1a91 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1120,50 +1120,211 @@
         }
     }
 
-    private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
+    private boolean validatePackageName(int uid, String packageName) {
+        if (packageName != null) {
+            String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+            if (packageNames != null) {
+                for (String n : packageNames) {
+                    if (n.equals(packageName)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean canProjectVideo(IMediaProjection projection) {
+        if (projection != null) {
+            try {
+                if (projection.canProjectVideo()) {
+                    return true;
+                }
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Unable to query projection service for permissions", e);
+            }
+        }
+        if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) {
+            return true;
+        }
+        return canProjectSecureVideo(projection);
+    }
+
+    private boolean canProjectSecureVideo(IMediaProjection projection) {
+        if (projection != null) {
+            try {
+                if (projection.canProjectSecureVideo()) {
+                    return true;
+                }
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Unable to query projection service for permissions", e);
+            }
+        }
+        return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()");
+    }
+
+    private boolean checkCallingPermission(String permission, String func) {
+        if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
+        final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
+                + ", uid=" + Binder.getCallingUid() + " requires " + permission;
+        Slog.w(TAG, msg);
+        return false;
+    }
+
+    private int createVirtualDisplayInternal(VirtualDisplayConfig virtualDisplayConfig,
+            IVirtualDisplayCallback callback, IMediaProjection projection, String packageName,
+            DisplayWindowPolicyController controller) {
+        final int callingUid = Binder.getCallingUid();
+        if (!validatePackageName(callingUid, packageName)) {
+            throw new SecurityException("packageName must match the calling uid");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("appToken must not be null");
+        }
+        if (virtualDisplayConfig == null) {
+            throw new IllegalArgumentException("virtualDisplayConfig must not be null");
+        }
+        final Surface surface = virtualDisplayConfig.getSurface();
+        int flags = virtualDisplayConfig.getFlags();
+
+        if (surface != null && surface.isSingleBuffered()) {
+            throw new IllegalArgumentException("Surface can't be single-buffered");
+        }
+
+        if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
+            flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
+
+            // Public displays can't be allowed to show content when locked.
+            if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
+                throw new IllegalArgumentException(
+                        "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
+            }
+        }
+        if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
+            flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
+        }
+        if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
+            flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
+        }
+
+        if (projection != null) {
+            try {
+                if (!getProjectionService().isValidMediaProjection(projection)) {
+                    throw new SecurityException("Invalid media projection");
+                }
+                flags = projection.applyVirtualDisplayFlags(flags);
+            } catch (RemoteException e) {
+                throw new SecurityException("unable to validate media projection or flags");
+            }
+        }
+
+        if (callingUid != Process.SYSTEM_UID
+                && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
+            if (!canProjectVideo(projection)) {
+                throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
+                        + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
+                        + "MediaProjection token in order to create a screen sharing virtual "
+                        + "display.");
+            }
+        }
+        if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
+            if (!canProjectSecureVideo(projection)) {
+                throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
+                        + "or an appropriate MediaProjection token to create a "
+                        + "secure virtual display.");
+            }
+        }
+
+        if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
+            if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
+                EventLog.writeEvent(0x534e4554, "162627132", callingUid,
+                        "Attempt to create a trusted display without holding permission!");
+                throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
+                        + "create a trusted virtual display.");
+            }
+        }
+
+        if (callingUid != Process.SYSTEM_UID
+                && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
+            if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
+                throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
+                        + "create a virtual display which is not in the default DisplayGroup.");
+            }
+        }
+
+        if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
+            flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
+        }
+
+        // Sometimes users can have sensitive information in system decoration windows. An app
+        // could create a virtual display with system decorations support and read the user info
+        // from the surface.
+        // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+        // to trusted virtual displays.
+        final int trustedDisplayWithSysDecorFlag =
+                (VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+                        | VIRTUAL_DISPLAY_FLAG_TRUSTED);
+        if ((flags & trustedDisplayWithSysDecorFlag)
+                == VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+                && !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
+            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSyncRoot) {
+                return createVirtualDisplayLocked(callback, projection, callingUid, packageName,
+                        surface, flags, virtualDisplayConfig, controller);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private int createVirtualDisplayLocked(IVirtualDisplayCallback callback,
             IMediaProjection projection, int callingUid, String packageName, Surface surface,
             int flags, VirtualDisplayConfig virtualDisplayConfig,
             DisplayWindowPolicyController controller) {
-        synchronized (mSyncRoot) {
-            if (mVirtualDisplayAdapter == null) {
-                Slog.w(TAG, "Rejecting request to create private virtual display "
-                        + "because the virtual display adapter is not available.");
-                return -1;
-            }
-
-            DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
-                    callback, projection, callingUid, packageName, surface, flags,
-                    virtualDisplayConfig);
-            if (device == null) {
-                return -1;
-            }
-
-            // DisplayDevice events are handled manually for Virtual Displays.
-            // TODO: multi-display Fix this so that generic add/remove events are not handled in a
-            // different code path for virtual displays.  Currently this happens so that we can
-            // return a valid display ID synchronously upon successful Virtual Display creation.
-            // This code can run on any binder thread, while onDisplayDeviceAdded() callbacks are
-            // called on the DisplayThread (which we don't want to wait for?).
-            // One option would be to actually wait here on the binder thread
-            // to be notified when the virtual display is created (or failed).
-            mDisplayDeviceRepo.onDisplayDeviceEvent(device,
-                    DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
-
-            final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
-            if (display != null) {
-                if (controller != null) {
-                    mDisplayWindowPolicyController.put(display.getDisplayIdLocked(), controller);
-                }
-                return display.getDisplayIdLocked();
-            }
-
-            // Something weird happened and the logical display was not created.
-            Slog.w(TAG, "Rejecting request to create virtual display "
-                    + "because the logical display was not created.");
-            mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
-            mDisplayDeviceRepo.onDisplayDeviceEvent(device,
-                    DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
+        if (mVirtualDisplayAdapter == null) {
+            Slog.w(TAG, "Rejecting request to create private virtual display "
+                    + "because the virtual display adapter is not available.");
+            return -1;
         }
+
+        DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
+                callback, projection, callingUid, packageName, surface, flags,
+                virtualDisplayConfig);
+        if (device == null) {
+            return -1;
+        }
+
+        // DisplayDevice events are handled manually for Virtual Displays.
+        // TODO: multi-display Fix this so that generic add/remove events are not handled in a
+        // different code path for virtual displays.  Currently this happens so that we can
+        // return a valid display ID synchronously upon successful Virtual Display creation.
+        // This code can run on any binder thread, while onDisplayDeviceAdded() callbacks are
+        // called on the DisplayThread (which we don't want to wait for?).
+        // One option would be to actually wait here on the binder thread
+        // to be notified when the virtual display is created (or failed).
+        mDisplayDeviceRepo.onDisplayDeviceEvent(device,
+                DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
+
+        final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
+        if (display != null) {
+            if (controller != null) {
+                mDisplayWindowPolicyController.put(display.getDisplayIdLocked(), controller);
+            }
+            return display.getDisplayIdLocked();
+        }
+
+        // Something weird happened and the logical display was not created.
+        Slog.w(TAG, "Rejecting request to create virtual display "
+                + "because the logical display was not created.");
+        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
+        mDisplayDeviceRepo.onDisplayDeviceEvent(device,
+                DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
         return -1;
     }
 
@@ -2726,116 +2887,8 @@
         @Override // Binder call
         public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
                 IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) {
-            return createVirtualDisplay(virtualDisplayConfig, callback, projection, packageName,
-                    null /* controller */);
-        }
-
-        public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
-                IVirtualDisplayCallback callback, IMediaProjection projection, String packageName,
-                DisplayWindowPolicyController controller) {
-            final int callingUid = Binder.getCallingUid();
-            if (!validatePackageName(callingUid, packageName)) {
-                throw new SecurityException("packageName must match the calling uid");
-            }
-            if (callback == null) {
-                throw new IllegalArgumentException("appToken must not be null");
-            }
-            if (virtualDisplayConfig == null) {
-                throw new IllegalArgumentException("virtualDisplayConfig must not be null");
-            }
-            final Surface surface = virtualDisplayConfig.getSurface();
-            int flags = virtualDisplayConfig.getFlags();
-
-            if (surface != null && surface.isSingleBuffered()) {
-                throw new IllegalArgumentException("Surface can't be single-buffered");
-            }
-
-            if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
-                flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
-
-                // Public displays can't be allowed to show content when locked.
-                if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
-                    throw new IllegalArgumentException(
-                            "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
-                }
-            }
-            if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
-                flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
-            }
-            if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
-                flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
-            }
-
-            if (projection != null) {
-                try {
-                    if (!getProjectionService().isValidMediaProjection(projection)) {
-                        throw new SecurityException("Invalid media projection");
-                    }
-                    flags = projection.applyVirtualDisplayFlags(flags);
-                } catch (RemoteException e) {
-                    throw new SecurityException("unable to validate media projection or flags");
-                }
-            }
-
-            if (callingUid != Process.SYSTEM_UID &&
-                    (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
-                if (!canProjectVideo(projection)) {
-                    throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
-                            + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
-                            + "MediaProjection token in order to create a screen sharing virtual "
-                            + "display.");
-                }
-            }
-            if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
-                if (!canProjectSecureVideo(projection)) {
-                    throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
-                            + "or an appropriate MediaProjection token to create a "
-                            + "secure virtual display.");
-                }
-            }
-
-            if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
-                if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
-                    EventLog.writeEvent(0x534e4554, "162627132", callingUid,
-                            "Attempt to create a trusted display without holding permission!");
-                    throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
-                            + "create a trusted virtual display.");
-                }
-            }
-
-            if (callingUid != Process.SYSTEM_UID
-                    && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
-                if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
-                    throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
-                            + "create a virtual display which is not in the default DisplayGroup.");
-                }
-            }
-
-            if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
-                flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
-            }
-
-            // Sometimes users can have sensitive information in system decoration windows. An app
-            // could create a virtual display with system decorations support and read the user info
-            // from the surface.
-            // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
-            // to trusted virtual displays.
-            final int trustedDisplayWithSysDecorFlag =
-                    (VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
-                            | VIRTUAL_DISPLAY_FLAG_TRUSTED);
-            if ((flags & trustedDisplayWithSysDecorFlag)
-                    == VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
-                    && !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
-                    throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
-            }
-
-            final long token = Binder.clearCallingIdentity();
-            try {
-                return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
-                        surface, flags, virtualDisplayConfig, controller);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+            return createVirtualDisplayInternal(virtualDisplayConfig, callback, projection,
+                    packageName, null /* controller */);
         }
 
         @Override // Binder call
@@ -3265,60 +3318,6 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
-
-        private boolean validatePackageName(int uid, String packageName) {
-            if (packageName != null) {
-                String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
-                if (packageNames != null) {
-                    for (String n : packageNames) {
-                        if (n.equals(packageName)) {
-                            return true;
-                        }
-                    }
-                }
-            }
-            return false;
-        }
-
-        private boolean canProjectVideo(IMediaProjection projection) {
-            if (projection != null) {
-                try {
-                    if (projection.canProjectVideo()) {
-                        return true;
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to query projection service for permissions", e);
-                }
-            }
-            if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) {
-                return true;
-            }
-            return canProjectSecureVideo(projection);
-        }
-
-        private boolean canProjectSecureVideo(IMediaProjection projection) {
-            if (projection != null) {
-                try {
-                    if (projection.canProjectSecureVideo()){
-                        return true;
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to query projection service for permissions", e);
-                }
-            }
-            return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()");
-        }
-
-        private boolean checkCallingPermission(String permission, String func) {
-            if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
-                return true;
-            }
-            final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid() + " requires " + permission;
-            Slog.w(TAG, msg);
-            return false;
-        }
-
     }
 
     private static boolean isValidBrightness(float brightness) {
@@ -3655,6 +3654,14 @@
         }
 
         @Override
+        public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
+                IVirtualDisplayCallback callback, IMediaProjection projection, String packageName,
+                DisplayWindowPolicyController controller) {
+            return createVirtualDisplayInternal(virtualDisplayConfig, callback, projection,
+                    packageName, controller);
+        }
+
+        @Override
         public DisplayWindowPolicyController getDisplayWindowPolicyController(int displayId) {
             synchronized (mSyncRoot) {
                 return mDisplayWindowPolicyController.get(displayId);
diff --git a/services/core/java/com/android/server/notification/VibratorHelper.java b/services/core/java/com/android/server/notification/VibratorHelper.java
index 5199ef6..be5f219 100644
--- a/services/core/java/com/android/server/notification/VibratorHelper.java
+++ b/services/core/java/com/android/server/notification/VibratorHelper.java
@@ -89,7 +89,7 @@
      */
     public void vibrate(VibrationEffect effect, AudioAttributes attrs, String reason) {
         mVibrator.vibrate(Process.SYSTEM_UID, PackageManagerService.PLATFORM_PACKAGE_NAME,
-                effect, reason, new VibrationAttributes.Builder(attrs, effect).build());
+                effect, reason, new VibrationAttributes.Builder(attrs).build());
     }
 
     /** Stop all notification vibrations (ringtone, alarm, notification usages). */
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index dca8654..6ec3405 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -318,7 +318,7 @@
     }
 
     @Nullable
-    List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags,
+    List<ResolveInfo> queryActivities(Intent intent, String resolvedType, long flags,
             int userId) {
         synchronized (mLock) {
             return mActivities.queryIntent(intent, resolvedType, flags, userId);
@@ -326,7 +326,7 @@
     }
 
     @Nullable
-    List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags,
+    List<ResolveInfo> queryActivities(Intent intent, String resolvedType, long flags,
             List<ParsedActivity> activities, int userId) {
         synchronized (mLock) {
             return mActivities.queryIntentForPackage(
@@ -335,14 +335,14 @@
     }
 
     @Nullable
-    List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags, int userId) {
+    List<ResolveInfo> queryProviders(Intent intent, String resolvedType, long flags, int userId) {
         synchronized (mLock) {
             return mProviders.queryIntent(intent, resolvedType, flags, userId);
         }
     }
 
     @Nullable
-    List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags,
+    List<ResolveInfo> queryProviders(Intent intent, String resolvedType, long flags,
             List<ParsedProvider> providers, int userId) {
         synchronized (mLock) {
             return mProviders.queryIntentForPackage(intent, resolvedType, flags, providers, userId);
@@ -350,7 +350,7 @@
     }
 
     @Nullable
-    List<ProviderInfo> queryProviders(String processName, String metaDataKey, int uid, int flags,
+    List<ProviderInfo> queryProviders(String processName, String metaDataKey, int uid, long flags,
             int userId) {
         if (!sUserManager.exists(userId)) {
             return null;
@@ -409,7 +409,7 @@
     }
 
     @Nullable
-    ProviderInfo queryProvider(String authority, int flags, int userId) {
+    ProviderInfo queryProvider(String authority, long flags, int userId) {
         synchronized (mLock) {
             final ParsedProvider p = mProvidersByAuthority.get(authority);
             if (p == null) {
@@ -480,14 +480,14 @@
     }
 
     @Nullable
-    List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags, int userId) {
+    List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, long flags, int userId) {
         synchronized (mLock) {
             return mReceivers.queryIntent(intent, resolvedType, flags, userId);
         }
     }
 
     @Nullable
-    List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags,
+    List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, long flags,
             List<ParsedActivity> receivers, int userId) {
         synchronized (mLock) {
             return mReceivers.queryIntentForPackage(intent, resolvedType, flags, receivers, userId);
@@ -495,14 +495,14 @@
     }
 
     @Nullable
-    List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags, int userId) {
+    List<ResolveInfo> queryServices(Intent intent, String resolvedType, long flags, int userId) {
         synchronized (mLock) {
             return mServices.queryIntent(intent, resolvedType, flags, userId);
         }
     }
 
     @Nullable
-    List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags,
+    List<ResolveInfo> queryServices(Intent intent, String resolvedType, long flags,
             List<ParsedService> services, int userId) {
         synchronized (mLock) {
             return mServices.queryIntentForPackage(intent, resolvedType, flags, services, userId);
@@ -1380,7 +1380,7 @@
             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
         }
 
-        List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
+        List<ResolveInfo> queryIntent(Intent intent, String resolvedType, long flags,
                 int userId) {
             if (!sUserManager.exists(userId)) {
                 return null;
@@ -1392,7 +1392,7 @@
         }
 
         List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
-                int flags, List<ParsedActivity> packageActivities, int userId) {
+                long flags, List<ParsedActivity> packageActivities, int userId) {
             if (!sUserManager.exists(userId)) {
                 return null;
             }
@@ -1669,7 +1669,7 @@
         // ActivityIntentResolver.
         protected final ArrayMap<ComponentName, ParsedActivity> mActivities =
                 new ArrayMap<>();
-        private int mFlags;
+        private long mFlags;
     }
 
     // Both receivers and activities share a class, but point to different get methods
@@ -1711,7 +1711,7 @@
         }
 
         @Nullable
-        List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
+        List<ResolveInfo> queryIntent(Intent intent, String resolvedType, long flags,
                 int userId) {
             if (!sUserManager.exists(userId)) {
                 return null;
@@ -1724,7 +1724,7 @@
 
         @Nullable
         List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
-                int flags, List<ParsedProvider> packageProviders, int userId) {
+                long flags, List<ParsedProvider> packageProviders, int userId) {
             if (!sUserManager.exists(userId)) {
                 return null;
             }
@@ -1946,7 +1946,7 @@
         }
 
         private final ArrayMap<ComponentName, ParsedProvider> mProviders = new ArrayMap<>();
-        private int mFlags;
+        private long mFlags;
     }
 
     private static final class ServiceIntentResolver
@@ -1969,7 +1969,7 @@
             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
         }
 
-        List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
+        List<ResolveInfo> queryIntent(Intent intent, String resolvedType, long flags,
                 int userId) {
             if (!sUserManager.exists(userId)) return null;
             mFlags = flags;
@@ -1979,7 +1979,7 @@
         }
 
         List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
-                int flags, List<ParsedService> packageServices, int userId) {
+                long flags, List<ParsedService> packageServices, int userId) {
             if (!sUserManager.exists(userId)) return null;
             if (packageServices == null) {
                 return Collections.emptyList();
@@ -2190,7 +2190,7 @@
 
         // Keys are String (activity class name), values are Activity.
         private final ArrayMap<ComponentName, ParsedService> mServices = new ArrayMap<>();
-        private int mFlags;
+        private long mFlags;
     }
 
     static final class InstantAppIntentResolver
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index a9df4ba..3e849f8 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -133,35 +133,36 @@
     }
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
-            int flags, @PackageManagerInternal.PrivateResolveFlags int privateResolveFlags,
+            @PackageManager.ResolveInfoFlags long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
             int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
-            int flags, int userId);
+            long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType,
-            int flags, int userId, int callingUid, boolean includeInstantApps);
+            long flags, int userId, int callingUid, boolean includeInstantApps);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
-            String resolvedType, int flags, int filterCallingUid, int userId,
+            String resolvedType, long flags, int filterCallingUid, int userId,
             boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
             String instantAppPkgName);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ActivityInfo getActivityInfo(ComponentName component, int flags, int userId);
+    ActivityInfo getActivityInfo(ComponentName component, long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
+    ActivityInfo getActivityInfoInternal(ComponentName component, long flags,
             int filterCallingUid, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     AndroidPackage getPackage(String packageName);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     AndroidPackage getPackage(int uid);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ApplicationInfo generateApplicationInfoFromSettings(String packageName, int flags,
+    ApplicationInfo generateApplicationInfoFromSettings(String packageName, long flags,
             int filterCallingUid, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ApplicationInfo getApplicationInfo(String packageName, int flags, int userId);
+    ApplicationInfo getApplicationInfo(String packageName, long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
+    ApplicationInfo getApplicationInfoInternal(String packageName, long flags,
             int filterCallingUid, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ComponentName getDefaultHomeActivity(int userId);
@@ -169,7 +170,7 @@
     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType,
-            int flags, int sourceUserId, int parentUserId);
+            long flags, int sourceUserId, int parentUserId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     Intent getHomeIntent();
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
@@ -180,11 +181,11 @@
             String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
             boolean resolveForStart, int userId, Intent intent);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    PackageInfo generatePackageInfo(PackageStateInternal ps, int flags, int userId);
+    PackageInfo generatePackageInfo(PackageStateInternal ps, long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    PackageInfo getPackageInfo(String packageName, int flags, int userId);
+    PackageInfo getPackageInfo(String packageName, long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    PackageInfo getPackageInfoInternal(String packageName, long versionCode, int flags,
+    PackageInfo getPackageInfoInternal(String packageName, long versionCode, long flags,
             int filterCallingUid, int userId);
 
     /**
@@ -202,12 +203,12 @@
     @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
     @Nullable PackageState getPackageStateCopied(@NonNull String packageName);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId);
+    ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
             int sourceUserId, int targetUserId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ServiceInfo getServiceInfo(ComponentName component, int flags, int userId);
+    ServiceInfo getServiceInfo(ComponentName component, long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     SharedLibraryInfo getSharedLibraryInfo(String name, long version);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
@@ -224,7 +225,7 @@
     boolean canViewInstantApps(int callingUid, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid, int userId,
-            int flags);
+            long flags);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isCallerSameApp(String packageName, int uid);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
@@ -234,7 +235,7 @@
             @PackageManager.ComponentType int type);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
-            String resolvedType, int flags);
+            String resolvedType, long flags);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     boolean isInstantApp(String packageName, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
@@ -254,18 +255,18 @@
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     int checkUidPermission(String permName, int uid);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.MANDATORY)
-    int getPackageUidInternal(String packageName, int flags, int userId, int callingUid);
+    int getPackageUidInternal(String packageName, long flags, int userId, int callingUid);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    int updateFlagsForApplication(int flags, int userId);
+    long updateFlagsForApplication(long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    int updateFlagsForComponent(int flags, int userId);
+    long updateFlagsForComponent(long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    int updateFlagsForPackage(int flags, int userId);
+    long updateFlagsForPackage(long flags, int userId);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
+    long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps,
             boolean isImplicitImageCaptureIntentAndNotSetByDpc);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
+    long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps,
             boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
@@ -291,10 +292,10 @@
     void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
-            Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always,
+            Intent intent, String resolvedType, long flags, List<ResolveInfo> query, boolean always,
             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered);
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
-    ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags,
+    ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, long flags,
             List<ResolveInfo> query, boolean debug, int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
@@ -337,7 +338,8 @@
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
-    int[] getPackageGids(@NonNull String packageName, int flags, @UserIdInt int userId);
+    int[] getPackageGids(@NonNull String packageName, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     int getTargetSdkVersion(@NonNull String packageName);
@@ -348,13 +350,13 @@
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
-    ActivityInfo getReceiverInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId);
+    ActivityInfo getReceiverInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ParceledListSlice<SharedLibraryInfo> getSharedLibraries(@NonNull String packageName,
-            int flags, @UserIdInt int userId);
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean canRequestPackageInstalls(@NonNull String packageName, int callingUid,
@@ -367,17 +369,18 @@
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
-            int flags, int callingUid, @UserIdInt int userId);
+            @PackageManager.PackageInfoFlags long flags, int callingUid, @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
     ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, int flags, @UserIdInt int userId);
+            @NonNull String packageName, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
-    ProviderInfo getProviderInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId);
+    ProviderInfo getProviderInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
@@ -436,17 +439,17 @@
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(@NonNull String[] permissions,
-            int flags, @UserIdInt int userId);
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
-    List<ApplicationInfo> getInstalledApplications(int flags, @UserIdInt int userId,
-            int callingUid);
+    List<ApplicationInfo> getInstalledApplications(@PackageManager.ApplicationInfoFlags long flags,
+            @UserIdInt int userId, int callingUid);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
-    ProviderInfo resolveContentProvider(@NonNull String name, int flags,
-            @UserIdInt int userId, int callingUid);
+    ProviderInfo resolveContentProvider(@NonNull String name,
+            @PackageManager.ResolveInfoFlags long flags, @UserIdInt int userId, int callingUid);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
@@ -460,7 +463,7 @@
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @NonNull
     ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName, int uid,
-            int flags, @Nullable String metaDataKey);
+            @PackageManager.ComponentInfoFlags long flags, @Nullable String metaDataKey);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     @Nullable
@@ -557,7 +560,8 @@
     boolean canQueryPackage(int callingUid, @Nullable String targetPackageName);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
-    int getPackageUid(@NonNull String packageName, int flags, @UserIdInt int userId);
+    int getPackageUid(@NonNull String packageName, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId);
 
     @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
     boolean canAccessComponent(int callingUid, @NonNull ComponentName component,
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 887dfff..2d61773 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -125,7 +125,6 @@
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
@@ -165,7 +164,6 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -215,7 +213,7 @@
 
         @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
         public boolean isEnabledAndMatch(AndroidPackage pkg, ParsedMainComponent component,
-                int flags, int userId) {
+                long flags, int userId) {
             PackageStateInternal pkgState = getPackage(component.getPackageName());
             if (pkgState == null) {
                 return false;
@@ -431,8 +429,8 @@
     }
 
     public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags,
-            @PackageManagerInternal.PrivateResolveFlags int privateResolveFlags,
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
             int filterCallingUid, int userId, boolean resolveForStart,
             boolean allowDynamicSplits) {
         if (!mUserManager.exists(userId)) return Collections.emptyList();
@@ -543,15 +541,15 @@
     }
 
     public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         return queryIntentActivitiesInternal(
                 intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
                 userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
     }
 
     public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
-            String resolvedType, int flags, int userId, int callingUid,
-            boolean includeInstantApps) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId,
+            int callingUid, boolean includeInstantApps) {
         if (!mUserManager.exists(userId)) return Collections.emptyList();
         enforceCrossUserOrProfilePermission(callingUid,
                 userId,
@@ -627,8 +625,8 @@
     }
 
     protected @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
-            String resolvedType, int flags, int userId, int callingUid,
-            String instantAppPkgName) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId,
+            int callingUid, String instantAppPkgName) {
         // reader
         String pkgName = intent.getPackage();
         if (pkgName == null) {
@@ -655,9 +653,9 @@
     }
 
     public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
-            Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
-            boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
-            String instantAppPkgName) {
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits,
+            String pkgName, String instantAppPkgName) {
         // reader
         boolean sortResult = false;
         boolean addInstant = false;
@@ -787,7 +785,8 @@
         return null;
     }
 
-    public final ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+    public final ActivityInfo getActivityInfo(ComponentName component,
+            @PackageManager.ResolveInfoFlags long flags, int userId) {
         return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
     }
 
@@ -797,8 +796,8 @@
      * to clearing. Because it can only be provided by trusted code, its value can be
      * trusted and will be used as-is; unlike userId which will be validated by this method.
      */
-    public final ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
-            int filterCallingUid, int userId) {
+    public final ActivityInfo getActivityInfoInternal(ComponentName component,
+            @PackageManager.ResolveInfoFlags long flags, int filterCallingUid, int userId) {
         if (!mUserManager.exists(userId)) return null;
         flags = updateFlagsForComponent(flags, userId);
 
@@ -811,8 +810,8 @@
         return getActivityInfoInternalBody(component, flags, filterCallingUid, userId);
     }
 
-    protected ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
-            int filterCallingUid, int userId) {
+    protected ActivityInfo getActivityInfoInternalBody(ComponentName component,
+            @PackageManager.ResolveInfoFlags long flags, int filterCallingUid, int userId) {
         ParsedActivity a = mComponentResolver.getActivity(component);
 
         if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
@@ -852,7 +851,7 @@
     }
 
     public final ApplicationInfo generateApplicationInfoFromSettings(String packageName,
-            int flags, int filterCallingUid, int userId) {
+            long flags, int filterCallingUid, int userId) {
         if (!mUserManager.exists(userId)) return null;
         PackageStateInternal ps = mSettings.getPackage(packageName);
         if (ps != null) {
@@ -879,7 +878,8 @@
         return null;
     }
 
-    public final ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+    public final ApplicationInfo getApplicationInfo(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags, int userId) {
         return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
     }
 
@@ -889,7 +889,8 @@
      * to clearing. Because it can only be provided by trusted code, its value can be
      * trusted and will be used as-is; unlike userId which will be validated by this method.
      */
-    public final ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
+    public final ApplicationInfo getApplicationInfoInternal(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags,
             int filterCallingUid, int userId) {
         if (!mUserManager.exists(userId)) return null;
         flags = updateFlagsForApplication(flags, userId);
@@ -903,7 +904,8 @@
         return getApplicationInfoInternalBody(packageName, flags, filterCallingUid, userId);
     }
 
-    protected ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
+    protected ApplicationInfo getApplicationInfoInternalBody(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags,
             int filterCallingUid, int userId) {
         // writer
         // Normalize package name to handle renamed packages and static libs
@@ -960,7 +962,7 @@
     }
 
     protected ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
-            Intent intent, int matchFlags, List<ResolveInfo> candidates,
+            Intent intent, long matchFlags, List<ResolveInfo> candidates,
             CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
         final ArrayList<ResolveInfo> result = new ArrayList<>();
         final ArrayList<ResolveInfo> matchAllList = new ArrayList<>();
@@ -1159,7 +1161,8 @@
     }
 
     public final CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
-            String resolvedType, int flags, int sourceUserId, int parentUserId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int sourceUserId,
+            int parentUserId) {
         if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
                 sourceUserId)) {
             return null;
@@ -1380,7 +1383,7 @@
     }
 
     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
-            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
+            long matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
             int userId) {
         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
 
@@ -1423,9 +1426,8 @@
     }
 
     private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result,
-            Intent intent,
-            String resolvedType, int flags, int userId, boolean resolveForStart,
-            boolean isRequesterInstantApp) {
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            int userId, boolean resolveForStart, boolean isRequesterInstantApp) {
         // first, check to see if we've got an instant app already installed
         final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
         ResolveInfo localInstantApp = null;
@@ -1529,7 +1531,8 @@
         return result;
     }
 
-    public final PackageInfo generatePackageInfo(PackageStateInternal ps, int flags, int userId) {
+    public final PackageInfo generatePackageInfo(PackageStateInternal ps,
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         if (!mUserManager.exists(userId)) return null;
         if (ps == null) {
             return null;
@@ -1603,7 +1606,8 @@
         }
     }
 
-    public final PackageInfo getPackageInfo(String packageName, int flags, int userId) {
+    public final PackageInfo getPackageInfo(String packageName,
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
                 flags, Binder.getCallingUid(), userId);
     }
@@ -1615,7 +1619,7 @@
      * trusted and will be used as-is; unlike userId which will be validated by this method.
      */
     public final PackageInfo getPackageInfoInternal(String packageName, long versionCode,
-            int flags, int filterCallingUid, int userId) {
+            long flags, int filterCallingUid, int userId) {
         if (!mUserManager.exists(userId)) return null;
         flags = updateFlagsForPackage(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId,
@@ -1626,7 +1630,7 @@
     }
 
     protected PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
-            int flags, int filterCallingUid, int userId) {
+            long flags, int filterCallingUid, int userId) {
         // reader
         // Normalize package name to handle renamed packages and static libs
         packageName = resolveInternalPackageNameLPr(packageName, versionCode);
@@ -1711,7 +1715,7 @@
         return pkgSetting == null ? null : PackageStateImpl.copy(pkgSetting);
     }
 
-    public final ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
+    public final ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId) {
         final int callingUid = Binder.getCallingUid();
         if (getInstantAppPackageName(callingUid) != null) {
             return ParceledListSlice.emptyList();
@@ -1725,7 +1729,7 @@
         return getInstalledPackagesBody(flags, userId, callingUid);
     }
 
-    protected ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
+    protected ParceledListSlice<PackageInfo> getInstalledPackagesBody(long flags, int userId,
             int callingUid) {
         // writer
         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
@@ -1804,7 +1808,8 @@
     @Nullable
     private CrossProfileDomainInfo createForwardingResolveInfo(
             @NonNull CrossProfileIntentFilter filter, @NonNull Intent intent,
-            @Nullable String resolvedType, int flags, int sourceUserId) {
+            @Nullable String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            int sourceUserId) {
         int targetUserId = filter.getTargetUserId();
         if (!isUserEnabled(targetUserId)) {
             return null;
@@ -1891,7 +1896,7 @@
     @Nullable
     private CrossProfileDomainInfo queryCrossProfileIntents(
             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
-            int flags, int sourceUserId, boolean matchInCurrentProfile) {
+            long flags, int sourceUserId, boolean matchInCurrentProfile) {
         if (matchingFilters == null) {
             return null;
         }
@@ -1945,7 +1950,7 @@
 
     private ResolveInfo querySkipCurrentProfileIntents(
             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
-            int flags, int sourceUserId) {
+            long flags, int sourceUserId) {
         if (matchingFilters != null) {
             int size = matchingFilters.size();
             for (int i = 0; i < size; i++) {
@@ -1964,7 +1969,8 @@
         return null;
     }
 
-    public final ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
+    public final ServiceInfo getServiceInfo(ComponentName component,
+            @PackageManager.ResolveInfoFlags long flags, int userId) {
         if (!mUserManager.exists(userId)) return null;
         final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForComponent(flags, userId);
@@ -1974,8 +1980,8 @@
         return getServiceInfoBody(component, flags, userId, callingUid);
     }
 
-    protected ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
-            int callingUid) {
+    protected ServiceInfo getServiceInfoBody(ComponentName component,
+            @PackageManager.ResolveInfoFlags long flags, int userId, int callingUid) {
         ParsedService s = mComponentResolver.getService(component);
         if (DEBUG_PACKAGE_INFO) {
             Log.v(
@@ -2227,7 +2233,7 @@
     }
 
     public final boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid,
-            int userId, int flags) {
+            int userId, @PackageManager.ComponentInfoFlags long flags) {
         // Callers can access only the libs they depend on, otherwise they need to explicitly
         // ask for the shared libraries given the caller is allowed to access all static libs.
         if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
@@ -2375,7 +2381,7 @@
      * activity was not set by the DPC.
      */
     public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
-            int userId, String resolvedType, int flags) {
+            int userId, String resolvedType, @PackageManager.ResolveInfoFlags long flags) {
         return intent.isImplicitImageCaptureIntent() && !isPersistentPreferredActivitySetByDpm(
                 intent, userId, resolvedType, flags);
     }
@@ -2416,7 +2422,7 @@
 
     private boolean isInstantAppResolutionAllowed(
             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
-            boolean skipPackageCheck, int flags) {
+            boolean skipPackageCheck, @PackageManager.ResolveInfoFlags long flags) {
         if (mInstantAppResolverConnection == null) {
             return false;
         }
@@ -2456,7 +2462,7 @@
     // Or if there's already an ephemeral app installed that handles the action
     protected boolean isInstantAppResolutionAllowedBody(
             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
-            boolean skipPackageCheck, int flags) {
+            boolean skipPackageCheck, @PackageManager.ResolveInfoFlags long flags) {
         final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
         for (int n = 0; n < count; n++) {
             final ResolveInfo info = resolvedActivities.get(n);
@@ -2488,7 +2494,7 @@
     }
 
     private boolean isPersistentPreferredActivitySetByDpm(Intent intent, int userId,
-            String resolvedType, int flags) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags) {
         PersistentPreferredIntentResolver ppir =
                 mSettings.getPersistentPreferredActivities(userId);
         //TODO(b/158003772): Remove double query
@@ -2645,8 +2651,8 @@
         return mPermissionManager.checkUidPermission(uid, permName);
     }
 
-    public int getPackageUidInternal(String packageName, int flags, int userId,
-            int callingUid) {
+    public int getPackageUidInternal(String packageName,
+            @PackageManager.PackageInfoFlags long flags, int userId, int callingUid) {
         // reader
         final AndroidPackage p = mPackages.get(packageName);
         if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
@@ -2670,7 +2676,7 @@
     /**
      * Update given flags based on encryption status of current user.
      */
-    private int updateFlags(int flags, int userId) {
+    private long updateFlags(long flags, int userId) {
         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
             // Caller expressed an explicit opinion about what encryption
@@ -2691,21 +2697,21 @@
     /**
      * Update given flags when being used to request {@link ApplicationInfo}.
      */
-    public final int updateFlagsForApplication(int flags, int userId) {
+    public final long updateFlagsForApplication(long flags, int userId) {
         return updateFlagsForPackage(flags, userId);
     }
 
     /**
      * Update given flags when being used to request {@link ComponentInfo}.
      */
-    public final int updateFlagsForComponent(int flags, int userId) {
+    public final long updateFlagsForComponent(long flags, int userId) {
         return updateFlags(flags, userId);
     }
 
     /**
      * Update given flags when being used to request {@link PackageInfo}.
      */
-    public final int updateFlagsForPackage(int flags, int userId) {
+    public final long updateFlagsForPackage(long flags, int userId) {
         final boolean isCallerSystemUser = UserHandle.getCallingUserId()
                 == UserHandle.USER_SYSTEM;
         if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
@@ -2741,14 +2747,14 @@
      * action and a {@code android.intent.category.BROWSABLE} category</li>
      * </ul>
      */
-    public final int updateFlagsForResolve(int flags, int userId, int callingUid,
+    public final long updateFlagsForResolve(long flags, int userId, int callingUid,
             boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
         return updateFlagsForResolve(flags, userId, callingUid,
                 wantInstantApps, false /*onlyExposedExplicitly*/,
                 isImplicitImageCaptureIntentAndNotSetByDpc);
     }
 
-    public final int updateFlagsForResolve(int flags, int userId, int callingUid,
+    public final long updateFlagsForResolve(long flags, int userId, int callingUid,
             boolean wantInstantApps, boolean onlyExposedExplicitly,
             boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
         // Safe mode means we shouldn't match any third-party components
@@ -3169,7 +3175,7 @@
 
     // The body of findPreferredActivity.
     protected PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityBody(
-            Intent intent, String resolvedType, int flags,
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
             List<ResolveInfo> query, boolean always,
             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered,
             int callingUid, boolean isDeviceProvisioned) {
@@ -3378,7 +3384,7 @@
     }
 
     public final PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
-            Intent intent, String resolvedType, int flags,
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
             List<ResolveInfo> query, boolean always,
             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
 
@@ -3395,8 +3401,8 @@
     }
 
     public final ResolveInfo findPersistentPreferredActivityLP(Intent intent,
-            String resolvedType,
-            int flags, List<ResolveInfo> query, boolean debug, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            List<ResolveInfo> query, boolean debug, int userId) {
         final int n = query.size();
         PersistentPreferredIntentResolver ppir =
                 mSettings.getPersistentPreferredActivities(userId);
@@ -3592,7 +3598,8 @@
     }
 
     @Override
-    public int[] getPackageGids(@NonNull String packageName, int flags, @UserIdInt int userId) {
+    public int[] getPackageGids(@NonNull String packageName,
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         if (!mUserManager.exists(userId)) return null;
         final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForPackage(flags, userId);
@@ -3668,8 +3675,8 @@
 
     @Nullable
     @Override
-    public ActivityInfo getReceiverInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ActivityInfo getReceiverInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         if (!mUserManager.exists(userId)) return null;
         final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForComponent(flags, userId);
@@ -3702,7 +3709,7 @@
     @Nullable
     @Override
     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(@NonNull String packageName,
-            int flags, @UserIdInt int userId) {
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         if (!mUserManager.exists(userId)) return null;
         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
         final int callingUid = Binder.getCallingUid();
@@ -3831,7 +3838,7 @@
 
     @Override
     public List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
-            int flags, int callingUid, @UserIdInt int userId) {
+            @PackageManager.PackageInfoFlags long flags, int callingUid, @UserIdInt int userId) {
         List<VersionedPackage> versionedPackages = null;
         final ArrayMap<String, ? extends PackageStateInternal> packageStates = getPackageStates();
         final int packageCount = packageStates.size();
@@ -3888,7 +3895,8 @@
     @Nullable
     @Override
     public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, int flags, @UserIdInt int userId) {
+            @NonNull String packageName, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
                 "getDeclaredSharedLibraries");
         int callingUid = Binder.getCallingUid();
@@ -3963,8 +3971,8 @@
 
     @Nullable
     @Override
-    public ProviderInfo getProviderInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ProviderInfo getProviderInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         if (!mUserManager.exists(userId)) return null;
         final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForComponent(flags, userId);
@@ -4438,7 +4446,8 @@
     @NonNull
     @Override
     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
-            @NonNull String[] permissions, int flags, @UserIdInt int userId) {
+            @NonNull String[] permissions, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId) {
         if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
         flags = updateFlagsForPackage(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
@@ -4458,7 +4467,8 @@
     }
 
     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageStateInternal ps,
-            String[] permissions, boolean[] tmp, int flags, int userId) {
+            String[] permissions, boolean[] tmp, @PackageManager.PackageInfoFlags long flags,
+            int userId) {
         int numMatch = 0;
         for (int i=0; i<permissions.length; i++) {
             final String permission = permissions[i];
@@ -4478,7 +4488,7 @@
         // The above might return null in cases of uninstalled apps or install-state
         // skew across users/profiles.
         if (pi != null) {
-            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
+            if ((flags & PackageManager.GET_PERMISSIONS) == 0) {
                 if (numMatch == permissions.length) {
                     pi.requestedPermissions = permissions;
                 } else {
@@ -4498,7 +4508,8 @@
 
     @NonNull
     @Override
-    public List<ApplicationInfo> getInstalledApplications(int flags, @UserIdInt int userId,
+    public List<ApplicationInfo> getInstalledApplications(
+            @PackageManager.ApplicationInfoFlags long flags, @UserIdInt int userId,
             int callingUid) {
         if (getInstantAppPackageName(callingUid) != null) {
             return Collections.emptyList();
@@ -4521,7 +4532,7 @@
             list = new ArrayList<>(packageStates.size());
             for (PackageStateInternal ps : packageStates.values()) {
                 ApplicationInfo ai;
-                int effectiveFlags = flags;
+                long effectiveFlags = flags;
                 if (ps.isSystem()) {
                     effectiveFlags |= PackageManager.MATCH_ANY_USER;
                 }
@@ -4574,8 +4585,8 @@
 
     @Nullable
     @Override
-    public ProviderInfo resolveContentProvider(@NonNull String name, int flags,
-            @UserIdInt int userId, int callingUid) {
+    public ProviderInfo resolveContentProvider(@NonNull String name,
+            @PackageManager.ResolveInfoFlags long flags, @UserIdInt int userId, int callingUid) {
         if (!mUserManager.exists(userId)) return null;
         flags = updateFlagsForComponent(flags, userId);
         final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
@@ -4664,7 +4675,7 @@
     @NonNull
     @Override
     public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
-            int uid, int flags, @Nullable String metaDataKey) {
+            int uid, @PackageManager.ComponentInfoFlags long flags, @Nullable String metaDataKey) {
         final int callingUid = Binder.getCallingUid();
         final int userId = processName != null ? UserHandle.getUserId(uid)
                 : UserHandle.getCallingUserId();
@@ -5209,7 +5220,8 @@
     }
 
     @Override
-    public int getPackageUid(@NonNull String packageName, int flags, @UserIdInt int userId) {
+    public int getPackageUid(@NonNull String packageName,
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         if (!mUserManager.exists(userId)) return -1;
         final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForPackage(flags, userId);
@@ -5312,7 +5324,7 @@
             if (parent == null) {
                 return false;
             }
-            int flags = updateFlagsForResolve(0, parent.id, callingUid,
+            long flags = updateFlagsForResolve(0, parent.id, callingUid,
                     false /*includeInstantApps*/,
                     isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, parent.id,
                             resolvedType, 0));
diff --git a/services/core/java/com/android/server/pm/ComputerLocked.java b/services/core/java/com/android/server/pm/ComputerLocked.java
index 801aaef..f180d19 100644
--- a/services/core/java/com/android/server/pm/ComputerLocked.java
+++ b/services/core/java/com/android/server/pm/ComputerLocked.java
@@ -29,6 +29,7 @@
 import android.content.pm.InstrumentationInfo;
 import android.content.pm.KeySet;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ProcessInfo;
 import android.content.pm.ProviderInfo;
@@ -89,7 +90,7 @@
         }
     }
     public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
-            Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
+            Intent intent, String resolvedType, long flags, int filterCallingUid, int userId,
             boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
             String instantAppPkgName) {
         synchronized (mLock) {
@@ -312,7 +313,8 @@
     }
 
     @Override
-    public int[] getPackageGids(@NonNull String packageName, int flags, @UserIdInt int userId) {
+    public int[] getPackageGids(@NonNull String packageName,
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getPackageGids(packageName, flags, userId);
         }
@@ -336,8 +338,8 @@
 
     @Nullable
     @Override
-    public ActivityInfo getReceiverInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ActivityInfo getReceiverInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getReceiverInfo(component, flags, userId);
         }
@@ -346,7 +348,7 @@
     @Nullable
     @Override
     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(@NonNull String packageName,
-            int flags, @UserIdInt int userId) {
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getSharedLibraries(packageName, flags, userId);
         }
@@ -363,7 +365,7 @@
 
     @Override
     public List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
-            int flags, int callingUid, @UserIdInt int userId) {
+            @PackageManager.PackageInfoFlags long flags, int callingUid, @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId);
         }
@@ -372,7 +374,8 @@
     @Nullable
     @Override
     public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, int flags, @UserIdInt int userId) {
+            @NonNull String packageName, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getDeclaredSharedLibraries(packageName, flags, userId);
         }
@@ -380,8 +383,8 @@
 
     @Nullable
     @Override
-    public ProviderInfo getProviderInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ProviderInfo getProviderInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getProviderInfo(component, flags, userId);
         }
@@ -495,7 +498,8 @@
     @NonNull
     @Override
     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
-            @NonNull String[] permissions, int flags, @UserIdInt int userId) {
+            @NonNull String[] permissions, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getPackagesHoldingPermissions(permissions, flags, userId);
         }
@@ -503,7 +507,8 @@
 
     @NonNull
     @Override
-    public List<ApplicationInfo> getInstalledApplications(int flags, @UserIdInt int userId,
+    public List<ApplicationInfo> getInstalledApplications(
+            @PackageManager.ApplicationInfoFlags long flags, @UserIdInt int userId,
             int callingUid) {
         synchronized (mLock) {
             return super.getInstalledApplications(flags, userId, callingUid);
@@ -512,8 +517,8 @@
 
     @Nullable
     @Override
-    public ProviderInfo resolveContentProvider(@NonNull String name, int flags,
-            @UserIdInt int userId, int callingUid) {
+    public ProviderInfo resolveContentProvider(@NonNull String name,
+            @PackageManager.ResolveInfoFlags long flags, @UserIdInt int userId, int callingUid) {
         synchronized (mLock) {
             return super.resolveContentProvider(name, flags, userId, callingUid);
         }
@@ -539,7 +544,7 @@
     @NonNull
     @Override
     public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
-            int uid, int flags, @Nullable String metaDataKey) {
+            int uid, @PackageManager.ComponentInfoFlags long flags, @Nullable String metaDataKey) {
         synchronized (mLock) {
             return super.queryContentProviders(processName, uid, flags, metaDataKey);
         }
@@ -711,7 +716,8 @@
     }
 
     @Override
-    public int getPackageUid(@NonNull String packageName, int flags, @UserIdInt int userId) {
+    public int getPackageUid(@NonNull String packageName,
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         synchronized (mLock) {
             return super.getPackageUid(packageName, flags, userId);
         }
diff --git a/services/core/java/com/android/server/pm/ComputerTracker.java b/services/core/java/com/android/server/pm/ComputerTracker.java
index ca17d66..a3cd092 100644
--- a/services/core/java/com/android/server/pm/ComputerTracker.java
+++ b/services/core/java/com/android/server/pm/ComputerTracker.java
@@ -97,8 +97,8 @@
     }
 
     public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags,
-            @PackageManagerInternal.PrivateResolveFlags int privateResolveFlags,
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
             int filterCallingUid, int userId, boolean resolveForStart,
             boolean allowDynamicSplits) {
         ThreadComputer current = snapshot();
@@ -111,7 +111,7 @@
         }
     }
     public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         ThreadComputer current = snapshot();
         try {
             return current.mComputer.queryIntentActivitiesInternal(intent, resolvedType, flags,
@@ -121,8 +121,8 @@
         }
     }
     public @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
-            String resolvedType, int flags, int userId, int callingUid,
-            boolean includeInstantApps) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId,
+            int callingUid, boolean includeInstantApps) {
         ThreadComputer current = snapshot();
         try {
             return current.mComputer.queryIntentServicesInternal(intent, resolvedType, flags,
@@ -132,10 +132,9 @@
         }
     }
     public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
-            Intent intent,
-            String resolvedType, int flags, int filterCallingUid, int userId,
-            boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
-            String instantAppPkgName) {
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits,
+            String pkgName, String instantAppPkgName) {
         ThreadComputer current = live();
         try {
             return current.mComputer.queryIntentActivitiesInternalBody(intent, resolvedType,
@@ -145,7 +144,8 @@
             current.release();
         }
     }
-    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+    public ActivityInfo getActivityInfo(ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, int userId) {
         ThreadComputer current = snapshot();
         try {
             return current.mComputer.getActivityInfo(component, flags, userId);
@@ -153,7 +153,8 @@
             current.release();
         }
     }
-    public ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
+    public ActivityInfo getActivityInfoInternal(ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags,
             int filterCallingUid, int userId) {
         ThreadComputer current = live();
         try {
@@ -180,7 +181,7 @@
         }
     }
     public ApplicationInfo generateApplicationInfoFromSettings(String packageName,
-            int flags, int filterCallingUid, int userId) {
+            long flags, int filterCallingUid, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.generateApplicationInfoFromSettings(packageName, flags,
@@ -189,7 +190,8 @@
             current.release();
         }
     }
-    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+    public ApplicationInfo getApplicationInfo(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags, int userId) {
         ThreadComputer current = snapshot();
         try {
             return current.mComputer.getApplicationInfo(packageName, flags, userId);
@@ -197,8 +199,8 @@
             current.release();
         }
     }
-    public ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
-            int filterCallingUid, int userId) {
+    public ApplicationInfo getApplicationInfoInternal(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags, int filterCallingUid, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.getApplicationInfoInternal(packageName, flags,
@@ -225,7 +227,8 @@
         }
     }
     public CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
-            String resolvedType, int flags, int sourceUserId, int parentUserId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int sourceUserId,
+            int parentUserId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.getCrossProfileDomainPreferredLpr(intent, resolvedType,
@@ -264,7 +267,8 @@
             current.release();
         }
     }
-    public PackageInfo generatePackageInfo(PackageStateInternal ps, int flags, int userId) {
+    public PackageInfo generatePackageInfo(PackageStateInternal ps,
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.generatePackageInfo(ps, flags, userId);
@@ -272,7 +276,8 @@
             current.release();
         }
     }
-    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
+    public PackageInfo getPackageInfo(String packageName,
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         ThreadComputer current = snapshot();
         try {
             return current.mComputer.getPackageInfo(packageName, flags, userId);
@@ -281,7 +286,7 @@
         }
     }
     public PackageInfo getPackageInfoInternal(String packageName, long versionCode,
-            int flags, int filterCallingUid, int userId) {
+            long flags, int filterCallingUid, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.getPackageInfoInternal(packageName, versionCode, flags,
@@ -317,7 +322,7 @@
         }
     }
 
-    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
+    public ParceledListSlice<PackageInfo> getInstalledPackages(long flags, int userId) {
         ThreadComputer current = snapshot();
         try {
             return current.mComputer.getInstalledPackages(flags, userId);
@@ -335,7 +340,8 @@
             current.release();
         }
     }
-    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
+    public ServiceInfo getServiceInfo(ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.getServiceInfo(component, flags, userId);
@@ -440,7 +446,7 @@
         }
     }
     public boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid,
-            int userId, int flags) {
+            int userId, @PackageManager.ComponentInfoFlags long flags) {
         ThreadComputer current = live();
         try {
             return current.mComputer.filterSharedLibPackage(ps, uid, userId, flags);
@@ -474,7 +480,7 @@
         }
     }
     public boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
-            int userId, String resolvedType, int flags) {
+            int userId, String resolvedType, @PackageManager.ResolveInfoFlags long flags) {
         ThreadComputer current = live();
         try {
             return current.mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent,
@@ -546,8 +552,8 @@
             current.release();
         }
     }
-    public int getPackageUidInternal(String packageName, int flags, int userId,
-            int callingUid) {
+    public int getPackageUidInternal(String packageName,
+            @PackageManager.PackageInfoFlags long flags, int userId, int callingUid) {
         ThreadComputer current = live();
         try {
             return current.mComputer.getPackageUidInternal(packageName, flags, userId,
@@ -556,7 +562,7 @@
             current.release();
         }
     }
-    public int updateFlagsForApplication(int flags, int userId) {
+    public long updateFlagsForApplication(long flags, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.updateFlagsForApplication(flags, userId);
@@ -564,7 +570,7 @@
             current.release();
         }
     }
-    public int updateFlagsForComponent(int flags, int userId) {
+    public long updateFlagsForComponent(long flags, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.updateFlagsForComponent(flags, userId);
@@ -572,7 +578,7 @@
             current.release();
         }
     }
-    public int updateFlagsForPackage(int flags, int userId) {
+    public long updateFlagsForPackage(long flags, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.updateFlagsForPackage(flags, userId);
@@ -580,7 +586,7 @@
             current.release();
         }
     }
-    public int updateFlagsForResolve(int flags, int userId, int callingUid,
+    public long updateFlagsForResolve(long flags, int userId, int callingUid,
             boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
         ThreadComputer current = snapshot();
         try {
@@ -590,7 +596,7 @@
             current.release();
         }
     }
-    public int updateFlagsForResolve(int flags, int userId, int callingUid,
+    public long updateFlagsForResolve(long flags, int userId, int callingUid,
             boolean wantInstantApps, boolean onlyExposedExplicitly,
             boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
         ThreadComputer current = live();
@@ -642,8 +648,9 @@
         }
     }
     public PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
-            Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always,
-            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug,
+            int userId, boolean queryMayBeFiltered) {
         ThreadComputer current = live();
         try {
             return current.mComputer.findPreferredActivityInternal(intent, resolvedType, flags,
@@ -653,8 +660,8 @@
         }
     }
     public ResolveInfo findPersistentPreferredActivityLP(Intent intent,
-            String resolvedType, int flags, List<ResolveInfo> query, boolean debug,
-            int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            List<ResolveInfo> query, boolean debug, int userId) {
         ThreadComputer current = live();
         try {
             return current.mComputer.findPersistentPreferredActivityLP(intent, resolvedType,
@@ -741,7 +748,8 @@
     }
 
     @Override
-    public int[] getPackageGids(@NonNull String packageName, int flags, @UserIdInt int userId) {
+    public int[] getPackageGids(@NonNull String packageName,
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getPackageGids(packageName, flags, userId);
         }
@@ -765,8 +773,8 @@
 
     @Nullable
     @Override
-    public ActivityInfo getReceiverInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ActivityInfo getReceiverInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getReceiverInfo(component, flags, userId);
         }
@@ -775,7 +783,7 @@
     @Nullable
     @Override
     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(@NonNull String packageName,
-            int flags, @UserIdInt int userId) {
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getSharedLibraries(packageName, flags, userId);
         }
@@ -800,7 +808,7 @@
 
     @Override
     public List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
-            int flags, int callingUid, @UserIdInt int userId) {
+            @PackageManager.PackageInfoFlags long flags, int callingUid, @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getPackagesUsingSharedLibrary(libInfo, flags, callingUid,
                     userId);
@@ -810,7 +818,8 @@
     @Nullable
     @Override
     public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, int flags, @UserIdInt int userId) {
+            @NonNull String packageName, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getDeclaredSharedLibraries(packageName, flags, userId);
         }
@@ -818,8 +827,8 @@
 
     @Nullable
     @Override
-    public ProviderInfo getProviderInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ProviderInfo getProviderInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getProviderInfo(component, flags, userId);
         }
@@ -934,7 +943,8 @@
     @NonNull
     @Override
     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
-            @NonNull String[] permissions, int flags, @UserIdInt int userId) {
+            @NonNull String[] permissions, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getPackagesHoldingPermissions(permissions, flags, userId);
         }
@@ -942,7 +952,8 @@
 
     @NonNull
     @Override
-    public List<ApplicationInfo> getInstalledApplications(int flags, @UserIdInt int userId,
+    public List<ApplicationInfo> getInstalledApplications(
+            @PackageManager.ApplicationInfoFlags long flags, @UserIdInt int userId,
             int callingUid) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getInstalledApplications(flags, userId, callingUid);
@@ -951,8 +962,8 @@
 
     @Nullable
     @Override
-    public ProviderInfo resolveContentProvider(@NonNull String name, int flags,
-            @UserIdInt int userId, int callingUid) {
+    public ProviderInfo resolveContentProvider(@NonNull String name,
+            @PackageManager.ResolveInfoFlags long flags, @UserIdInt int userId, int callingUid) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.resolveContentProvider(name, flags, userId, callingUid);
         }
@@ -979,7 +990,7 @@
     @NonNull
     @Override
     public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable String processName,
-            int uid, int flags, @Nullable String metaDataKey) {
+            int uid, @PackageManager.ComponentInfoFlags long flags, @Nullable String metaDataKey) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.queryContentProviders(processName, uid, flags, metaDataKey);
         }
@@ -1152,7 +1163,8 @@
     }
 
     @Override
-    public int getPackageUid(@NonNull String packageName, int flags, @UserIdInt int userId) {
+    public int getPackageUid(@NonNull String packageName,
+            @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         try (ThreadComputer current = snapshot()) {
             return current.mComputer.getPackageUid(packageName, flags, userId);
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b664978..9f5adcb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2576,8 +2576,8 @@
         return mComputer.canViewInstantApps(callingUid, userId);
     }
 
-    private PackageInfo generatePackageInfo(@NonNull PackageStateInternal ps, int flags,
-            int userId) {
+    private PackageInfo generatePackageInfo(@NonNull PackageStateInternal ps,
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         return mComputer.generatePackageInfo(ps, flags, userId);
     }
 
@@ -2616,13 +2616,14 @@
     }
 
     @Override
-    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
+    public PackageInfo getPackageInfo(String packageName,
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         return mComputer.getPackageInfo(packageName, flags, userId);
     }
 
     @Override
     public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
-            int flags, int userId) {
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         return mComputer.getPackageInfoInternal(versionedPackage.getPackageName(),
                 versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
     }
@@ -2659,7 +2660,7 @@
     }
 
     private boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid,
-            int userId, int flags) {
+            int userId, @PackageManager.ComponentInfoFlags long flags) {
         return mComputer.filterSharedLibPackage(ps, uid, userId, flags);
     }
 
@@ -2674,16 +2675,19 @@
     }
 
     @Override
-    public int getPackageUid(@NonNull String packageName, int flags, @UserIdInt int userId) {
+    public int getPackageUid(@NonNull String packageName,
+        @PackageManager.PackageInfoFlags long flags, @UserIdInt int userId) {
         return mComputer.getPackageUid(packageName, flags, userId);
     }
 
-    private int getPackageUidInternal(String packageName, int flags, int userId, int callingUid) {
+    private int getPackageUidInternal(String packageName,
+            @PackageManager.PackageInfoFlags long flags, int userId, int callingUid) {
         return mComputer.getPackageUidInternal(packageName, flags, userId, callingUid);
     }
 
     @Override
-    public int[] getPackageGids(String packageName, int flags, int userId) {
+    public int[] getPackageGids(String packageName, @PackageManager.PackageInfoFlags long flags,
+            int userId) {
         return mComputer.getPackageGids(packageName, flags, userId);
     }
 
@@ -2696,14 +2700,15 @@
                 .getPermissionGroupInfo(groupName, flags);
     }
 
-    private ApplicationInfo generateApplicationInfoFromSettings(String packageName, int flags,
-            int filterCallingUid, int userId) {
-        return mComputer.generateApplicationInfoFromSettings(packageName, flags,
-                filterCallingUid, userId);
+    private ApplicationInfo generateApplicationInfoFromSettings(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags, int filterCallingUid, int userId) {
+        return mComputer.generateApplicationInfoFromSettings(packageName, flags, filterCallingUid,
+                userId);
     }
 
     @Override
-    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+    public ApplicationInfo getApplicationInfo(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags, int userId) {
         return mComputer.getApplicationInfo(packageName, flags, userId);
     }
 
@@ -2713,7 +2718,8 @@
      * to clearing. Because it can only be provided by trusted code, its value can be
      * trusted and will be used as-is; unlike userId which will be validated by this method.
      */
-    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
+    private ApplicationInfo getApplicationInfoInternal(String packageName,
+            @PackageManager.ApplicationInfoFlags long flags,
             int filterCallingUid, int userId) {
         return mComputer.getApplicationInfoInternal(packageName, flags,
                 filterCallingUid, userId);
@@ -2948,21 +2954,21 @@
     /**
      * Update given flags when being used to request {@link PackageInfo}.
      */
-    private int updateFlagsForPackage(int flags, int userId) {
+    private long updateFlagsForPackage(long flags, int userId) {
         return mComputer.updateFlagsForPackage(flags, userId);
     }
 
     /**
      * Update given flags when being used to request {@link ApplicationInfo}.
      */
-    private int updateFlagsForApplication(int flags, int userId) {
+    private long updateFlagsForApplication(long flags, int userId) {
         return mComputer.updateFlagsForApplication(flags, userId);
     }
 
     /**
      * Update given flags when being used to request {@link ComponentInfo}.
      */
-    private int updateFlagsForComponent(int flags, int userId) {
+    private long updateFlagsForComponent(long flags, int userId) {
         return mComputer.updateFlagsForComponent(flags, userId);
     }
 
@@ -2978,7 +2984,7 @@
      * action and a {@code android.intent.category.BROWSABLE} category</li>
      * </ul>
      */
-    int updateFlagsForResolve(int flags, int userId, int callingUid,
+    long updateFlagsForResolve(long flags, int userId, int callingUid,
             boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
         return mComputer.updateFlagsForResolve(flags, userId, callingUid,
                 wantInstantApps, isImplicitImageCaptureIntentAndNotSetByDpc);
@@ -2990,7 +2996,8 @@
     }
 
     @Override
-    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+    public ActivityInfo getActivityInfo(ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, int userId) {
         return mComputer.getActivityInfo(component, flags, userId);
     }
 
@@ -3000,8 +3007,8 @@
      * to clearing. Because it can only be provided by trusted code, its value can be
      * trusted and will be used as-is; unlike userId which will be validated by this method.
      */
-    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
-            int filterCallingUid, int userId) {
+    private ActivityInfo getActivityInfoInternal(ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, int filterCallingUid, int userId) {
         return mComputer.getActivityInfoInternal(component, flags,
                 filterCallingUid, userId);
     }
@@ -3014,40 +3021,43 @@
     }
 
     @Override
-    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
+    public ActivityInfo getReceiverInfo(ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, int userId) {
         return mComputer.getReceiverInfo(component, flags, userId);
     }
 
     @Override
     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
-            int flags, int userId) {
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         return mComputer.getSharedLibraries(packageName, flags, userId);
     }
 
     @Nullable
     @Override
     public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
-            @NonNull String packageName, int flags, @UserIdInt int userId) {
+            @NonNull String packageName, @PackageManager.PackageInfoFlags long flags,
+            @NonNull int userId) {
         return mComputer.getDeclaredSharedLibraries(packageName, flags, userId);
     }
 
     @Nullable
     List<VersionedPackage> getPackagesUsingSharedLibrary(
-            SharedLibraryInfo libInfo, int flags, int callingUid, int userId) {
+            SharedLibraryInfo libInfo, @PackageManager.PackageInfoFlags long flags, int callingUid,
+            int userId) {
         return mComputer.getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId);
     }
 
     @Nullable
     @Override
-    public ServiceInfo getServiceInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ServiceInfo getServiceInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         return mComputer.getServiceInfo(component, flags, userId);
     }
 
     @Nullable
     @Override
-    public ProviderInfo getProviderInfo(@NonNull ComponentName component, int flags,
-            @UserIdInt int userId) {
+    public ProviderInfo getProviderInfo(@NonNull ComponentName component,
+            @PackageManager.ComponentInfoFlags long flags, @UserIdInt int userId) {
         return mComputer.getProviderInfo(component, flags, userId);
     }
 
@@ -3336,7 +3346,7 @@
 
     @Override
     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
-            int flags, int userId) {
+            @PackageManager.ResolveInfoFlags long flags, int userId) {
         return mResolveIntentHelper.resolveIntentInternal(intent, resolvedType, flags,
                 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
     }
@@ -3381,7 +3391,7 @@
      */
     @GuardedBy("mLock")
     boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
-            String resolvedType, int flags) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags) {
         return mComputer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
                 resolvedType, flags);
     }
@@ -3389,10 +3399,10 @@
     @GuardedBy("mLock")
     ResolveInfo findPersistentPreferredActivityLP(Intent intent,
             String resolvedType,
-            int flags, List<ResolveInfo> query, boolean debug, int userId) {
+            @PackageManager.ResolveInfoFlags long flags, List<ResolveInfo> query, boolean debug,
+            int userId) {
         return mComputer.findPersistentPreferredActivityLP(intent,
-                resolvedType,
-                flags, query, debug, userId);
+                resolvedType, flags, query, debug, userId);
     }
 
     // findPreferredActivityBody returns two items: a "things changed" flag and a
@@ -3403,7 +3413,7 @@
     }
 
     FindPreferredActivityBodyResult findPreferredActivityInternal(
-            Intent intent, String resolvedType, int flags,
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
             List<ResolveInfo> query, boolean always,
             boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
         return mComputer.findPreferredActivityInternal(
@@ -3433,7 +3443,7 @@
 
     @Override
     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         try {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
 
@@ -3453,21 +3463,23 @@
     }
 
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         return mComputer.queryIntentActivitiesInternal(intent,
                 resolvedType, flags, userId);
     }
 
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
-            int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            @PrivateResolveFlags long privateResolveFlags, int filterCallingUid, int userId,
+            boolean resolveForStart, boolean allowDynamicSplits) {
         return mComputer.queryIntentActivitiesInternal(intent,
                 resolvedType, flags, privateResolveFlags,
                 filterCallingUid, userId, resolveForStart, allowDynamicSplits);
     }
 
     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
-            String resolvedType, int flags, int sourceUserId, int parentUserId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int sourceUserId,
+            int parentUserId) {
         return mComputer.getCrossProfileDomainPreferredLpr(intent,
                 resolvedType, flags, sourceUserId, parentUserId);
     }
@@ -3494,20 +3506,21 @@
     @Override
     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
             Intent[] specifics, String[] specificTypes, Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal(
                 caller, specifics, specificTypes, intent, resolvedType, flags, userId));
     }
 
     @Override
     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(intent,
                 resolvedType, flags, userId, Binder.getCallingUid()));
     }
 
     @Override
-    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
+    public ResolveInfo resolveService(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlags long flags, int userId) {
         final int callingUid = Binder.getCallingUid();
         return mResolveIntentHelper.resolveServiceInternal(intent, resolvedType, flags, userId,
                 callingUid);
@@ -3515,15 +3528,15 @@
 
     @Override
     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         final int callingUid = Binder.getCallingUid();
         return new ParceledListSlice<>(queryIntentServicesInternal(
                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
     }
 
     @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
-            String resolvedType, int flags, int userId, int callingUid,
-            boolean includeInstantApps) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId,
+            int callingUid, boolean includeInstantApps) {
         return mComputer.queryIntentServicesInternal(intent,
                 resolvedType, flags, userId, callingUid,
                 includeInstantApps);
@@ -3531,24 +3544,27 @@
 
     @Override
     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal(
                 intent, resolvedType, flags, userId));
     }
 
     @Override
-    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
+    public ParceledListSlice<PackageInfo> getInstalledPackages(
+            @PackageManager.PackageInfoFlags long flags, int userId) {
         return mComputer.getInstalledPackages(flags, userId);
     }
 
     @Override
     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
-            @NonNull String[] permissions, int flags, @UserIdInt int userId) {
+            @NonNull String[] permissions, @PackageManager.PackageInfoFlags long flags,
+            @UserIdInt int userId) {
         return mComputer.getPackagesHoldingPermissions(permissions, flags, userId);
     }
 
     @Override
-    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
+    public ParceledListSlice<ApplicationInfo> getInstalledApplications(
+            @PackageManager.ApplicationInfoFlags long flags, int userId) {
         final int callingUid = Binder.getCallingUid();
         return new ParceledListSlice<>(
                 mComputer.getInstalledApplications(flags, userId, callingUid));
@@ -3652,7 +3668,8 @@
     }
 
     @Override
-    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
+    public ProviderInfo resolveContentProvider(String name,
+            @PackageManager.ResolveInfoFlags long flags, int userId) {
         return mComputer.resolveContentProvider(name, flags, userId, Binder.getCallingUid());
     }
 
@@ -3664,7 +3681,7 @@
     @NonNull
     @Override
     public ParceledListSlice<ProviderInfo> queryContentProviders(@Nullable  String processName,
-            int uid, int flags, @Nullable String metaDataKey) {
+            int uid, @PackageManager.ComponentInfoFlags long flags, @Nullable String metaDataKey) {
         return mComputer.queryContentProviders(processName, uid, flags, metaDataKey);
     }
 
@@ -7509,8 +7526,8 @@
 
     private class PackageManagerInternalImpl extends PackageManagerInternal {
         @Override
-        public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
-                int callingUid) {
+        public List<ApplicationInfo> getInstalledApplications(
+                @PackageManager.ApplicationInfoFlags long flags, int userId, int callingUid) {
             return PackageManagerService.this.mComputer.getInstalledApplications(flags, userId,
                     callingUid);
         }
@@ -7705,7 +7722,8 @@
 
         @Override
         public PackageInfo getPackageInfo(
-                String packageName, int flags, int filterCallingUid, int userId) {
+                String packageName, @PackageManager.PackageInfoFlags long flags,
+                int filterCallingUid, int userId) {
             return PackageManagerService.this.mComputer
                     .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
                             flags, filterCallingUid, userId);
@@ -7833,28 +7851,32 @@
         }
 
         @Override
-        public int getPackageUid(String packageName, int flags, int userId) {
+        public int getPackageUid(String packageName, @PackageManager.PackageInfoFlags long flags,
+                int userId) {
             return PackageManagerService.this
                     .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
         }
 
         @Override
         public ApplicationInfo getApplicationInfo(
-                String packageName, int flags, int filterCallingUid, int userId) {
+                String packageName, @PackageManager.ApplicationInfoFlags long flags,
+                int filterCallingUid, int userId) {
             return PackageManagerService.this
                     .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
         }
 
         @Override
         public ActivityInfo getActivityInfo(
-                ComponentName component, int flags, int filterCallingUid, int userId) {
+                ComponentName component, @PackageManager.ComponentInfoFlags long flags,
+                int filterCallingUid, int userId) {
             return PackageManagerService.this
                     .getActivityInfoInternal(component, flags, filterCallingUid, userId);
         }
 
         @Override
         public List<ResolveInfo> queryIntentActivities(
-                Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
+                Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+                int filterCallingUid, int userId) {
             return PackageManagerService.this
                     .queryIntentActivitiesInternal(intent, resolvedType, flags, 0, filterCallingUid,
                             userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
@@ -7862,14 +7884,16 @@
 
         @Override
         public List<ResolveInfo> queryIntentReceivers(Intent intent,
-                String resolvedType, int flags, int filterCallingUid, int userId) {
+                String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+                int filterCallingUid, int userId) {
             return PackageManagerService.this.mResolveIntentHelper.queryIntentReceiversInternal(
                     intent, resolvedType, flags, userId, filterCallingUid);
         }
 
         @Override
         public List<ResolveInfo> queryIntentServices(
-                Intent intent, int flags, int callingUid, int userId) {
+                Intent intent, @PackageManager.ResolveInfoFlags long flags, int callingUid,
+                int userId) {
             final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
             return PackageManagerService.this
                     .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
@@ -7935,7 +7959,7 @@
         }
 
         @Override
-        public boolean isEnabledAndMatches(ParsedMainComponent component, int flags, int userId) {
+        public boolean isEnabledAndMatches(ParsedMainComponent component, long flags, int userId) {
             return PackageStateUtils.isEnabledAndMatches(
                     getPackageStateInternal(component.getPackageName()), component, flags, userId);
         }
@@ -8137,8 +8161,9 @@
 
         @Override
         public ResolveInfo resolveIntent(Intent intent, String resolvedType,
-                int flags, int privateResolveFlags, int userId, boolean resolveForStart,
-                int filterCallingUid) {
+                @PackageManager.ResolveInfoFlags long flags,
+                @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
+                boolean resolveForStart, int filterCallingUid) {
             return mResolveIntentHelper.resolveIntentInternal(
                     intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
                     filterCallingUid);
@@ -8146,14 +8171,14 @@
 
         @Override
         public ResolveInfo resolveService(Intent intent, String resolvedType,
-                int flags, int userId, int callingUid) {
+                @PackageManager.ResolveInfoFlags long flags, int userId, int callingUid) {
             return mResolveIntentHelper.resolveServiceInternal(intent, resolvedType, flags, userId,
                     callingUid);
         }
 
         @Override
-        public ProviderInfo resolveContentProvider(String name, int flags, int userId,
-                int callingUid) {
+        public ProviderInfo resolveContentProvider(String name,
+                @PackageManager.ResolveInfoFlags long flags, int userId, int callingUid) {
             return PackageManagerService.this.mComputer
                     .resolveContentProvider(name, flags, userId,callingUid);
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 1848ef5..3b643b5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -1079,7 +1079,7 @@
     public static boolean hasAnyDomainApproval(
             @NonNull DomainVerificationManagerInternal manager,
             @NonNull PackageStateInternal pkgSetting, @NonNull Intent intent,
-            @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) {
+            @PackageManager.ResolveInfoFlags long resolveInfoFlags, @UserIdInt int userId) {
         return manager.approvalLevelForDomain(pkgSetting, intent, resolveInfoFlags, userId)
                 > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE;
     }
diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
index cb97e2a..8c91b16 100644
--- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java
+++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
@@ -75,8 +75,8 @@
     }
 
     private ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType,
-            int flags, List<ResolveInfo> query, boolean always, boolean removeMatches,
-            boolean debug, int userId) {
+            @PackageManager.ResolveInfoFlags long flags, List<ResolveInfo> query, boolean always,
+            boolean removeMatches, boolean debug, int userId) {
         return findPreferredActivityNotLocked(
                 intent, resolvedType, flags, query, always, removeMatches, debug, userId,
                 UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID);
@@ -85,8 +85,9 @@
     // TODO: handle preferred activities missing while user has amnesia
     /** <b>must not hold {@link PackageManagerService.mLock}</b> */
     public ResolveInfo findPreferredActivityNotLocked(
-            Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean always,
-            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            List<ResolveInfo> query, boolean always, boolean removeMatches, boolean debug,
+            int userId, boolean queryMayBeFiltered) {
         if (Thread.holdsLock(mPm.mLock)) {
             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                     + " is holding mLock", new Throwable());
@@ -675,7 +676,7 @@
         final int callingUid = Binder.getCallingUid();
         intent = PackageManagerServiceUtils.updateIntentForResolve(intent);
         final String resolvedType = intent.resolveTypeIfNeeded(mPm.mContext.getContentResolver());
-        final int flags = mPm.updateFlagsForResolve(
+        final long flags = mPm.updateFlagsForResolve(
                 0, userId, callingUid, false /*includeInstantApps*/,
                 mPm.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
                         0));
diff --git a/services/core/java/com/android/server/pm/ResolveIntentHelper.java b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
index 70855a9..0ee1f89 100644
--- a/services/core/java/com/android/server/pm/ResolveIntentHelper.java
+++ b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
@@ -74,8 +74,9 @@
      * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
      * since we need to allow the system to start any installed application.
      */
-    public ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, int flags,
-            @PackageManagerInternal.PrivateResolveFlags int privateResolveFlags, int userId,
+    public ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlags long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
             boolean resolveForStart, int filterCallingUid) {
         try {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
@@ -114,8 +115,9 @@
     }
 
     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
-            int flags, int privateResolveFlags, List<ResolveInfo> query, int userId,
-            boolean queryMayBeFiltered) {
+            @PackageManager.ResolveInfoFlags long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
+            List<ResolveInfo> query, int userId, boolean queryMayBeFiltered) {
         if (query != null) {
             final int n = query.size();
             if (n == 1) {
@@ -276,7 +278,8 @@
     // In this method, we have to know the actual calling UID, but in some cases Binder's
     // call identity is removed, so the UID has to be passed in explicitly.
     public @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
-            String resolvedType, int flags, int userId, int filterCallingUid) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId,
+            int filterCallingUid) {
         if (!mPm.mUserManager.exists(userId)) return Collections.emptyList();
         mPm.enforceCrossUserPermission(filterCallingUid, userId, false /*requireFullPermission*/,
                 false /*checkShell*/, "query intent receivers");
@@ -370,8 +373,8 @@
     }
 
 
-    public ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
-            int userId, int callingUid) {
+    public ResolveInfo resolveServiceInternal(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlags long flags, int userId, int callingUid) {
         if (!mPm.mUserManager.exists(userId)) return null;
         flags = mPm.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
                 false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
@@ -388,7 +391,8 @@
     }
 
     public @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
-            Intent intent, String resolvedType, int flags, int userId) {
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlags long flags,
+            int userId) {
         if (!mPm.mUserManager.exists(userId)) return Collections.emptyList();
         final int callingUid = Binder.getCallingUid();
         final String instantAppPkgName = mPm.getInstantAppPackageName(callingUid);
@@ -529,7 +533,7 @@
 
     public @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
             Intent[] specifics, String[] specificTypes, Intent intent,
-            String resolvedType, int flags, int userId) {
+            String resolvedType, @PackageManager.ResolveInfoFlags long flags, int userId) {
         if (!mPm.mUserManager.exists(userId)) return Collections.emptyList();
         final int callingUid = Binder.getCallingUid();
         flags = mPm.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 1f5d79c..6a163b2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -154,7 +154,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
@@ -4150,7 +4149,7 @@
         return getDisabledSystemPkgLPr(enabledPackageSetting.getPackageName());
     }
 
-    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
+    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, long flags, int userId) {
         final PackageSetting ps = mPackages.get(componentInfo.packageName);
         if (ps == null) return false;
 
@@ -4160,7 +4159,7 @@
 
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     public boolean isEnabledAndMatchLPr(AndroidPackage pkg, ParsedMainComponent component,
-            int flags, int userId) {
+            long flags, int userId) {
         final PackageSetting ps = mPackages.get(component.getPackageName());
         if (ps == null) return false;
 
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index d54acb7..a5a8d5c 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -24,20 +24,6 @@
       "name": "CtsMatchFlagTestCases"
     },
     {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "include-filter": "com.android.server.pm."
-        },
-        {
-          "include-annotation": "android.platform.test.annotations.Presubmit"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        }
-      ]
-    },
-    {
       "name": "FrameworksMockingServicesTests",
       "options": [
         {
@@ -46,45 +32,6 @@
       ]
     },
     {
-      "name": "FrameworksServicesTests",
-      "file_patterns": ["(/|^)ShortcutService\\.java"],
-      "options": [
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest1"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest2"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest3"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest4"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest5"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest6"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest7"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest8"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest9"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest10"
-        },
-        {
-          "include-filter": "com.android.server.pm.ShortcutManagerTest11"
-        }
-      ]
-    },
-    {
       "name": "CtsShortcutHostTestCases",
       "file_patterns": ["(/|^)ShortcutService\\.java"]
     },
@@ -188,47 +135,6 @@
     },
     {
       "name": "PackageManagerServiceHostTests"
-    },
-    {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "install-arg": "-t"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserDataPreparerTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserLifecycleStressTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserManagerServiceCreateProfileTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserManagerServiceIdRecyclingTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserManagerServiceTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserManagerServiceUserInfoTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserManagerServiceUserTypeTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserManagerTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserRestrictionsUtilsTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.UserSystemPackageInstallerTest"
-        },
-        {
-          "include-filter": "com.android.server.pm.parsing.SystemPartitionParseTest"
-        }
-      ]
     }
   ],
   "imports": [
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 0ab1d36..bcb5e72 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -84,8 +84,8 @@
      */
     @Nullable
     public static PackageInfo generate(AndroidPackage pkg, int[] gids,
-            @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
-            Set<String> grantedPermissions, PackageUserState state, int userId,
+            @PackageManager.PackageInfoFlags long flags, long firstInstallTime,
+            long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId,
             @Nullable PackageStateInternal pkgSetting) {
         return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime,
                 grantedPermissions, state, userId, null, pkgSetting);
@@ -105,8 +105,8 @@
      * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
      */
     private static PackageInfo generateWithComponents(AndroidPackage pkg, int[] gids,
-            @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
-            Set<String> grantedPermissions, PackageUserState state, int userId,
+            @PackageManager.PackageInfoFlags long flags, long firstInstallTime,
+            long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId,
             @Nullable ApexInfo apexInfo, @Nullable PackageStateInternal pkgSetting) {
         ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId,
                 pkgSetting);
@@ -209,7 +209,7 @@
      */
     @Nullable
     public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg,
-            @PackageManager.ApplicationInfoFlags int flags, @NonNull PackageUserState state,
+            @PackageManager.ApplicationInfoFlags long flags, @NonNull PackageUserState state,
             int userId, @Nullable PackageStateInternal pkgSetting) {
         if (pkg == null) {
             return null;
@@ -255,7 +255,7 @@
      */
     @Nullable
     public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
-            @PackageManager.ComponentInfoFlags int flags, PackageUserState state, int userId,
+            @PackageManager.ComponentInfoFlags long flags, PackageUserState state, int userId,
             @Nullable PackageStateInternal pkgSetting) {
         return generateActivityInfo(pkg, a, flags, state, null, userId, pkgSetting);
     }
@@ -265,7 +265,7 @@
      */
     @Nullable
     private static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
-            @PackageManager.ComponentInfoFlags int flags, PackageUserState state,
+            @PackageManager.ComponentInfoFlags long flags, PackageUserState state,
             @Nullable ApplicationInfo applicationInfo, int userId,
             @Nullable PackageStateInternal pkgSetting) {
         if (a == null) return null;
@@ -291,7 +291,7 @@
      */
     @Nullable
     public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s,
-            @PackageManager.ComponentInfoFlags int flags, PackageUserState state, int userId,
+            @PackageManager.ComponentInfoFlags long flags, PackageUserState state, int userId,
             @Nullable PackageStateInternal pkgSetting) {
         return generateServiceInfo(pkg, s, flags, state, null, userId, pkgSetting);
     }
@@ -301,7 +301,7 @@
      */
     @Nullable
     private static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s,
-            @PackageManager.ComponentInfoFlags int flags, PackageUserState state,
+            @PackageManager.ComponentInfoFlags long flags, PackageUserState state,
             @Nullable ApplicationInfo applicationInfo, int userId,
             @Nullable PackageStateInternal pkgSetting) {
         if (s == null) return null;
@@ -326,7 +326,7 @@
      */
     @Nullable
     public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p,
-            @PackageManager.ComponentInfoFlags int flags, PackageUserState state,
+            @PackageManager.ComponentInfoFlags long flags, PackageUserState state,
             @NonNull ApplicationInfo applicationInfo, int userId,
             @Nullable PackageStateInternal pkgSetting) {
         if (p == null) return null;
@@ -353,7 +353,7 @@
      */
     @Nullable
     public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
-            AndroidPackage pkg, @PackageManager.ComponentInfoFlags int flags, int userId,
+            AndroidPackage pkg, @PackageManager.ComponentInfoFlags long flags, int userId,
             @Nullable PackageStateInternal pkgSetting) {
         if (i == null) return null;
 
@@ -381,7 +381,7 @@
     //  PackageStateInternal os that checkUseInstalledOrHidden filter can apply
     @Nullable
     public static PermissionInfo generatePermissionInfo(ParsedPermission p,
-            @PackageManager.ComponentInfoFlags int flags) {
+            @PackageManager.ComponentInfoFlags long flags) {
         // TODO(b/135203078): Remove null checks and make all usages @NonNull
         if (p == null) return null;
 
@@ -391,7 +391,7 @@
 
     @Nullable
     public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg,
-            @PackageManager.ComponentInfoFlags int flags) {
+            @PackageManager.ComponentInfoFlags long flags) {
         if (pg == null) return null;
 
         // For now, permissions don't have state-adjustable fields; return directly
@@ -400,7 +400,7 @@
 
     @Nullable
     public static ArrayMap<String, ProcessInfo> generateProcessInfo(
-            Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlags int flags) {
+            Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlags long flags) {
         if (procs == null) {
             return null;
         }
@@ -423,7 +423,7 @@
      */
     public static boolean checkUseInstalledOrHidden(AndroidPackage pkg,
             PackageStateInternal pkgSetting, PackageUserState state,
-            @PackageManager.PackageInfoFlags int flags) {
+            @PackageManager.PackageInfoFlags long flags) {
         // Returns false if the package is hidden system app until installed.
         if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
                 && !state.isInstalled()
@@ -628,7 +628,7 @@
          */
         @Nullable
         public ApplicationInfo generate(AndroidPackage pkg,
-                @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId,
+                @PackageManager.ApplicationInfoFlags long flags, PackageUserState state, int userId,
                 @Nullable PackageStateInternal pkgSetting) {
             ApplicationInfo appInfo = mCache.get(pkg.getPackageName());
             if (appInfo != null) {
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
index 61fd5ee..32b1e5d 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
@@ -256,7 +256,7 @@
      * Returns false iff the provided flags include the {@link PackageManager#MATCH_SYSTEM_ONLY}
      * flag and the provided package is not a system package. Otherwise returns {@code true}.
      */
-    public static boolean isMatchForSystemOnly(AndroidPackage pkg, int flags) {
+    public static boolean isMatchForSystemOnly(AndroidPackage pkg, long flags) {
         if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
             return pkg.isSystem();
         }
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java b/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java
index 6744ff5..09b9d31 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java
@@ -27,7 +27,7 @@
 
 public class PackageStateUtils {
 
-    public static boolean isMatch(PackageState packageState, int flags) {
+    public static boolean isMatch(PackageState packageState, long flags) {
         if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
             return packageState.isSystem();
         }
@@ -54,7 +54,7 @@
     }
 
     public static boolean isEnabledAndMatches(@Nullable PackageStateInternal packageState,
-            ComponentInfo componentInfo, int flags, int userId) {
+            ComponentInfo componentInfo, long flags, int userId) {
         if (packageState == null) return false;
 
         final PackageUserState userState = packageState.getUserStateOrDefault(userId);
@@ -62,7 +62,7 @@
     }
 
     public static boolean isEnabledAndMatches(@Nullable PackageStateInternal packageState,
-            @NonNull ParsedMainComponent component, int flags, int userId) {
+            @NonNull ParsedMainComponent component, long flags, int userId) {
         if (packageState == null) {
             return false;
         }
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java
index 1f024ea..471f38a 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java
@@ -391,7 +391,7 @@
      */
     @ApprovalLevel
     int approvalLevelForDomain(@NonNull PackageStateInternal pkgSetting, @NonNull Intent intent,
-            @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId);
+            @PackageManager.ResolveInfoFlags long resolveInfoFlags, @UserIdInt int userId);
 
     /**
      * @return the domain verification set ID for the given package, or null if the ID is
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
index 0fb8475..661e67d 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
@@ -1721,7 +1721,7 @@
 
     @Override
     public int approvalLevelForDomain(@NonNull PackageStateInternal pkgSetting,
-            @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags,
+            @NonNull Intent intent, @PackageManager.ResolveInfoFlags long resolveInfoFlags,
             @UserIdInt int userId) {
         String packageName = pkgSetting.getPackageName();
         if (!DomainVerificationUtils.isDomainVerificationIntent(intent, resolveInfoFlags)) {
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java
index 246810f..12cce0d 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java
@@ -49,7 +49,7 @@
     }
 
     public static boolean isDomainVerificationIntent(Intent intent,
-            @PackageManager.ResolveInfoFlags int resolveInfoFlags) {
+            @PackageManager.ResolveInfoFlags long resolveInfoFlags) {
         if (!intent.isWebIntent()) {
             return false;
         }
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 3182290..eb69ff7 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -64,6 +64,8 @@
 import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
 import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
 
+import static libcore.io.IoUtils.closeQuietly;
+
 import static java.lang.Math.min;
 import static java.util.concurrent.TimeUnit.HOURS;
 import static java.util.concurrent.TimeUnit.MICROSECONDS;
@@ -222,6 +224,7 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -3413,9 +3416,12 @@
                     metricsState.getGeoDetectionEnabledSetting(),
                     convertToMetricsDetectionMode(metricsState.getDetectionMode()),
                     metricsState.getDeviceTimeZoneIdOrdinal(),
-                    metricsState.getLatestManualSuggestionProtoBytes(),
-                    metricsState.getLatestTelephonySuggestionProtoBytes(),
-                    metricsState.getLatestGeolocationSuggestionProtoBytes()
+                    convertTimeZoneSuggestionToProtoBytes(
+                            metricsState.getLatestManualSuggestion()),
+                    convertTimeZoneSuggestionToProtoBytes(
+                            metricsState.getLatestTelephonySuggestion()),
+                    convertTimeZoneSuggestionToProtoBytes(
+                            metricsState.getLatestGeolocationSuggestion())
             ));
         } catch (RuntimeException e) {
             Slog.e(TAG, "Getting time zone detection state failed: ", e);
@@ -3426,7 +3432,8 @@
         return StatsManager.PULL_SUCCESS;
     }
 
-    private int convertToMetricsDetectionMode(int detectionMode) {
+    private static int convertToMetricsDetectionMode(
+            @MetricsTimeZoneDetectorState.DetectionMode int detectionMode) {
         switch (detectionMode) {
             case MetricsTimeZoneDetectorState.DETECTION_MODE_MANUAL:
                 return TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__MANUAL;
@@ -3439,6 +3446,34 @@
         }
     }
 
+    @Nullable
+    private static byte[] convertTimeZoneSuggestionToProtoBytes(
+            @Nullable MetricsTimeZoneDetectorState.MetricsTimeZoneSuggestion suggestion) {
+        if (suggestion == null) {
+            return null;
+        }
+
+        // We don't get access to the atoms.proto definition for nested proto fields, so we use
+        // an identically specified proto.
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        ProtoOutputStream protoOutputStream = new ProtoOutputStream(byteArrayOutputStream);
+        int typeProtoValue = suggestion.isCertain()
+                ? android.app.time.MetricsTimeZoneSuggestion.CERTAIN
+                : android.app.time.MetricsTimeZoneSuggestion.UNCERTAIN;
+        protoOutputStream.write(android.app.time.MetricsTimeZoneSuggestion.TYPE,
+                typeProtoValue);
+        if (suggestion.isCertain()) {
+            for (int zoneIdOrdinal : suggestion.getZoneIdOrdinals()) {
+                protoOutputStream.write(
+                        android.app.time.MetricsTimeZoneSuggestion.TIME_ZONE_ORDINALS,
+                        zoneIdOrdinal);
+            }
+        }
+        protoOutputStream.flush();
+        closeQuietly(byteArrayOutputStream);
+        return byteArrayOutputStream.toByteArray();
+    }
+
     private void registerExternalStorageInfo() {
         int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
         mStatsManager.setPullAtomCallback(
diff --git a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java
index 0c20586..f156f8c 100644
--- a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java
+++ b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java
@@ -16,16 +16,12 @@
 
 package com.android.server.timezonedetector;
 
-import static libcore.io.IoUtils.closeQuietly;
-
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.timezonedetector.ManualTimeZoneSuggestion;
 import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
-import android.util.proto.ProtoOutputStream;
 
-import java.io.ByteArrayOutputStream;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -50,7 +46,7 @@
             value = { DETECTION_MODE_MANUAL, DETECTION_MODE_GEO, DETECTION_MODE_TELEPHONY})
     @Retention(RetentionPolicy.SOURCE)
     @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
-    @interface DetectionMode {};
+    public @interface DetectionMode {};
 
     public static final @DetectionMode int DETECTION_MODE_MANUAL = 0;
     public static final @DetectionMode int DETECTION_MODE_GEO = 1;
@@ -89,16 +85,16 @@
 
         int deviceTimeZoneIdOrdinal =
                 tzIdOrdinalGenerator.ordinal(Objects.requireNonNull(deviceTimeZoneId));
-        MetricsTimeZoneSuggestion latestObfuscatedManualSuggestion =
+        MetricsTimeZoneSuggestion latestCanonicalManualSuggestion =
                 createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestManualSuggestion);
-        MetricsTimeZoneSuggestion latestObfuscatedTelephonySuggestion =
+        MetricsTimeZoneSuggestion latestCanonicalTelephonySuggestion =
                 createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestTelephonySuggestion);
-        MetricsTimeZoneSuggestion latestObfuscatedGeolocationSuggestion =
+        MetricsTimeZoneSuggestion latestCanonicalGeolocationSuggestion =
                 createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestGeolocationSuggestion);
 
         return new MetricsTimeZoneDetectorState(
-                configurationInternal, deviceTimeZoneIdOrdinal, latestObfuscatedManualSuggestion,
-                latestObfuscatedTelephonySuggestion, latestObfuscatedGeolocationSuggestion);
+                configurationInternal, deviceTimeZoneIdOrdinal, latestCanonicalManualSuggestion,
+                latestCanonicalTelephonySuggestion, latestCanonicalGeolocationSuggestion);
     }
 
     /** Returns true if the device supports telephony time zone detection. */
@@ -154,30 +150,27 @@
     }
 
     /**
-     * Returns bytes[] for a {@link MetricsTimeZoneSuggestion} for the last manual
-     * suggestion received.
+     * Returns a canonical form of the last manual suggestion received.
      */
     @Nullable
-    public byte[] getLatestManualSuggestionProtoBytes() {
-        return suggestionProtoBytes(mLatestManualSuggestion);
+    public MetricsTimeZoneSuggestion getLatestManualSuggestion() {
+        return mLatestManualSuggestion;
     }
 
     /**
-     * Returns bytes[] for a {@link MetricsTimeZoneSuggestion} for the last, best
-     * telephony suggestion received.
+     * Returns a canonical form of the last telephony suggestion received.
      */
     @Nullable
-    public byte[] getLatestTelephonySuggestionProtoBytes() {
-        return suggestionProtoBytes(mLatestTelephonySuggestion);
+    public MetricsTimeZoneSuggestion getLatestTelephonySuggestion() {
+        return mLatestTelephonySuggestion;
     }
 
     /**
-     * Returns bytes[] for a {@link MetricsTimeZoneSuggestion} for the last geolocation
-     * suggestion received.
+     * Returns a canonical form of last geolocation suggestion received.
      */
     @Nullable
-    public byte[] getLatestGeolocationSuggestionProtoBytes() {
-        return suggestionProtoBytes(mLatestGeolocationSuggestion);
+    public MetricsTimeZoneSuggestion getLatestGeolocationSuggestion() {
+        return mLatestGeolocationSuggestion;
     }
 
     @Override
@@ -213,14 +206,6 @@
                 + '}';
     }
 
-    private static byte[] suggestionProtoBytes(
-            @Nullable MetricsTimeZoneSuggestion suggestion) {
-        if (suggestion == null) {
-            return null;
-        }
-        return suggestion.toBytes();
-    }
-
     @Nullable
     private static MetricsTimeZoneSuggestion createMetricsTimeZoneSuggestion(
             @NonNull OrdinalGenerator<String> zoneIdOrdinalGenerator,
@@ -264,10 +249,11 @@
     }
 
     /**
-     * A Java class that closely matches the android.app.time.MetricsTimeZoneSuggestion
-     * proto definition.
+     * A Java class that represents a generic time zone suggestion, i.e. one that is independent of
+     * origin-specific information. This closely matches the metrics atoms.proto
+     * MetricsTimeZoneSuggestion proto definition.
      */
-    private static final class MetricsTimeZoneSuggestion {
+    public static final class MetricsTimeZoneSuggestion {
         @Nullable
         private final int[] mZoneIdOrdinals;
 
@@ -281,42 +267,20 @@
         }
 
         @NonNull
-        public static MetricsTimeZoneSuggestion createCertain(
+        static MetricsTimeZoneSuggestion createCertain(
                 @NonNull int[] zoneIdOrdinals) {
             return new MetricsTimeZoneSuggestion(zoneIdOrdinals);
         }
 
-        boolean isCertain() {
+        public boolean isCertain() {
             return mZoneIdOrdinals != null;
         }
 
         @Nullable
-        int[] getZoneIdOrdinals() {
+        public int[] getZoneIdOrdinals() {
             return mZoneIdOrdinals;
         }
 
-        byte[] toBytes() {
-            // We don't get access to the atoms.proto definition for nested proto fields, so we use
-            // an identically specified proto.
-            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-            ProtoOutputStream protoOutputStream = new ProtoOutputStream(byteArrayOutputStream);
-            int typeProtoValue = isCertain()
-                    ? android.app.time.MetricsTimeZoneSuggestion.CERTAIN
-                    : android.app.time.MetricsTimeZoneSuggestion.UNCERTAIN;
-            protoOutputStream.write(android.app.time.MetricsTimeZoneSuggestion.TYPE,
-                    typeProtoValue);
-            if (isCertain()) {
-                for (int zoneIdOrdinal : getZoneIdOrdinals()) {
-                    protoOutputStream.write(
-                            android.app.time.MetricsTimeZoneSuggestion.TIME_ZONE_ORDINALS,
-                            zoneIdOrdinal);
-                }
-            }
-            protoOutputStream.flush();
-            closeQuietly(byteArrayOutputStream);
-            return byteArrayOutputStream.toByteArray();
-        }
-
         @Override
         public boolean equals(Object o) {
             if (this == o) {
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
index 984b9ba..692b0cc 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
@@ -172,12 +172,13 @@
      * Enables/disables the state recording mode for tests. The value is reset with {@link
      * #resetVolatileTestConfig()}.
      */
-    void setRecordProviderStateChanges(boolean enabled);
+    void setRecordStateChangesForTests(boolean enabled);
 
     /**
-     * Returns {@code true} if providers are expected to record their state changes for tests.
+     * Returns {@code true} if the controller / providers are expected to record their state changes
+     * for tests.
      */
-    boolean getRecordProviderStateChanges();
+    boolean getRecordStateChangesForTests();
 
     /**
      * Returns the mode for the primary location time zone provider.
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
index b9885d2..02ea433 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
@@ -150,7 +150,7 @@
      * See also {@link #resetVolatileTestConfig()}.
      */
     @GuardedBy("this")
-    private boolean mRecordProviderStateChanges;
+    private boolean mRecordStateChangesForTests;
 
     private ServiceConfigAccessorImpl(@NonNull Context context) {
         mContext = Objects.requireNonNull(context);
@@ -453,13 +453,13 @@
     }
 
     @Override
-    public synchronized void setRecordProviderStateChanges(boolean enabled) {
-        mRecordProviderStateChanges = enabled;
+    public synchronized void setRecordStateChangesForTests(boolean enabled) {
+        mRecordStateChangesForTests = enabled;
     }
 
     @Override
-    public synchronized boolean getRecordProviderStateChanges() {
-        return mRecordProviderStateChanges;
+    public synchronized boolean getRecordStateChangesForTests() {
+        return mRecordStateChangesForTests;
     }
 
     @Override
@@ -548,7 +548,7 @@
         mTestPrimaryLocationTimeZoneProviderMode = null;
         mTestSecondaryLocationTimeZoneProviderPackageName = null;
         mTestSecondaryLocationTimeZoneProviderMode = null;
-        mRecordProviderStateChanges = false;
+        mRecordStateChangesForTests = false;
     }
 
     private boolean isTelephonyFallbackSupported() {
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
index af8cf6e..b23f11a 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
@@ -247,8 +247,7 @@
      * completion, it cannot be called from the {@code mThreadingDomain} thread.
      */
     void startWithTestProviders(@Nullable String testPrimaryProviderPackageName,
-            @Nullable String testSecondaryProviderPackageName,
-            boolean recordProviderStateChanges) {
+            @Nullable String testSecondaryProviderPackageName, boolean recordStateChanges) {
         enforceManageTimeZoneDetectorPermission();
 
         if (testPrimaryProviderPackageName == null && testSecondaryProviderPackageName == null) {
@@ -263,7 +262,7 @@
                         testPrimaryProviderPackageName);
                 mServiceConfigAccessor.setTestSecondaryLocationTimeZoneProviderPackageName(
                         testSecondaryProviderPackageName);
-                mServiceConfigAccessor.setRecordProviderStateChanges(recordProviderStateChanges);
+                mServiceConfigAccessor.setRecordStateChangesForTests(recordStateChanges);
                 startOnDomainThread();
             }
         }, BLOCKING_OP_WAIT_DURATION_MILLIS);
@@ -281,10 +280,20 @@
             if (mLocationTimeZoneProviderController == null) {
                 LocationTimeZoneProvider primary = mPrimaryProviderConfig.createProvider();
                 LocationTimeZoneProvider secondary = mSecondaryProviderConfig.createProvider();
+                LocationTimeZoneProviderController.MetricsLogger metricsLogger =
+                        new LocationTimeZoneProviderController.MetricsLogger() {
+                            @Override
+                            public void onStateChange(
+                                    @LocationTimeZoneProviderController.State String state) {
+                                // TODO b/200279201 - wire this up to metrics code
+                                // No-op.
+                            }
+                        };
 
+                boolean recordStateChanges = mServiceConfigAccessor.getRecordStateChangesForTests();
                 LocationTimeZoneProviderController controller =
-                        new LocationTimeZoneProviderController(
-                                mThreadingDomain, primary, secondary);
+                        new LocationTimeZoneProviderController(mThreadingDomain, metricsLogger,
+                                primary, secondary, recordStateChanges);
                 LocationTimeZoneProviderControllerEnvironmentImpl environment =
                         new LocationTimeZoneProviderControllerEnvironmentImpl(
                                 mThreadingDomain, mServiceConfigAccessor, controller);
@@ -342,7 +351,7 @@
         mThreadingDomain.postAndWait(() -> {
             synchronized (mSharedLock) {
                 if (mLocationTimeZoneProviderController != null) {
-                    mLocationTimeZoneProviderController.clearRecordedProviderStates();
+                    mLocationTimeZoneProviderController.clearRecordedStates();
                 }
             }
         }, BLOCKING_OP_WAIT_DURATION_MILLIS);
@@ -450,7 +459,7 @@
             ProviderMetricsLogger providerMetricsLogger = new RealProviderMetricsLogger(mIndex);
             return new BinderLocationTimeZoneProvider(
                     providerMetricsLogger, mThreadingDomain, mName, proxy,
-                    mServiceConfigAccessor.getRecordProviderStateChanges());
+                    mServiceConfigAccessor.getRecordStateChangesForTests());
         }
 
         @Override
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerServiceState.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerServiceState.java
index 113926a..1f752f4 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerServiceState.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerServiceState.java
@@ -21,6 +21,7 @@
 
 import com.android.server.timezonedetector.GeolocationTimeZoneSuggestion;
 import com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState;
+import com.android.server.timezonedetector.location.LocationTimeZoneProviderController.State;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -30,22 +31,35 @@
 /** A snapshot of the location time zone manager service's state for tests. */
 final class LocationTimeZoneManagerServiceState {
 
+    private final @State String mControllerState;
     @Nullable private final GeolocationTimeZoneSuggestion mLastSuggestion;
+    @NonNull private final List<@State String> mControllerStates;
     @NonNull private final List<ProviderState> mPrimaryProviderStates;
     @NonNull private final List<ProviderState> mSecondaryProviderStates;
 
     LocationTimeZoneManagerServiceState(@NonNull Builder builder) {
+        mControllerState = builder.mControllerState;
         mLastSuggestion = builder.mLastSuggestion;
+        mControllerStates = Objects.requireNonNull(builder.mControllerStates);
         mPrimaryProviderStates = Objects.requireNonNull(builder.mPrimaryProviderStates);
         mSecondaryProviderStates = Objects.requireNonNull(builder.mSecondaryProviderStates);
     }
 
+    public @State String getControllerState() {
+        return mControllerState;
+    }
+
     @Nullable
     public GeolocationTimeZoneSuggestion getLastSuggestion() {
         return mLastSuggestion;
     }
 
     @NonNull
+    public List<@State String> getControllerStates() {
+        return mControllerStates;
+    }
+
+    @NonNull
     public List<ProviderState> getPrimaryProviderStates() {
         return Collections.unmodifiableList(mPrimaryProviderStates);
     }
@@ -58,7 +72,9 @@
     @Override
     public String toString() {
         return "LocationTimeZoneManagerServiceState{"
-                + "mLastSuggestion=" + mLastSuggestion
+                + "mControllerState=" + mControllerState
+                + ", mLastSuggestion=" + mLastSuggestion
+                + ", mControllerStates=" + mControllerStates
                 + ", mPrimaryProviderStates=" + mPrimaryProviderStates
                 + ", mSecondaryProviderStates=" + mSecondaryProviderStates
                 + '}';
@@ -66,17 +82,31 @@
 
     static final class Builder {
 
+        private @State String mControllerState;
         private GeolocationTimeZoneSuggestion mLastSuggestion;
+        private List<@State String> mControllerStates;
         private List<ProviderState> mPrimaryProviderStates;
         private List<ProviderState> mSecondaryProviderStates;
 
         @NonNull
+        public Builder setControllerState(@State String stateEnum) {
+            mControllerState = stateEnum;
+            return this;
+        }
+
+        @NonNull
         Builder setLastSuggestion(@NonNull GeolocationTimeZoneSuggestion lastSuggestion) {
             mLastSuggestion = Objects.requireNonNull(lastSuggestion);
             return this;
         }
 
         @NonNull
+        public Builder setStateChanges(@NonNull List<@State String> states) {
+            mControllerStates = new ArrayList<>(states);
+            return this;
+        }
+
+        @NonNull
         Builder setPrimaryProviderStateChanges(@NonNull List<ProviderState> primaryProviderStates) {
             mPrimaryProviderStates = new ArrayList<>(primaryProviderStates);
             return this;
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerShellCommand.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerShellCommand.java
index 6c9e174..60bbea7 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerShellCommand.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerShellCommand.java
@@ -40,6 +40,14 @@
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_UNCERTAIN;
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STOPPED;
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_UNKNOWN;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_CERTAIN;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_DESTROYED;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_FAILED;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_INITIALIZING;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_PROVIDERS_INITIALIZING;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_STOPPED;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_UNCERTAIN;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_UNKNOWN;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -55,6 +63,7 @@
 import com.android.internal.util.dump.DualDumpOutputStream;
 import com.android.server.timezonedetector.GeolocationTimeZoneSuggestion;
 import com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.ProviderStateEnum;
+import com.android.server.timezonedetector.location.LocationTimeZoneProviderController.State;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -245,6 +254,7 @@
             outputStream.end(lastSuggestionToken);
         }
 
+        writeControllerStates(outputStream, state.getControllerStates());
         writeProviderStates(outputStream, state.getPrimaryProviderStates(),
                 "primary_provider_states",
                 LocationTimeZoneManagerServiceStateProto.PRIMARY_PROVIDER_STATES);
@@ -256,6 +266,37 @@
         return 0;
     }
 
+    private static void writeControllerStates(DualDumpOutputStream outputStream,
+            List<@State String> states) {
+        for (@State String state : states) {
+            outputStream.write("controller_states",
+                    LocationTimeZoneManagerServiceStateProto.CONTROLLER_STATES,
+                    convertControllerStateToProtoEnum(state));
+        }
+    }
+
+    private static int convertControllerStateToProtoEnum(@State String state) {
+        switch (state) {
+            case STATE_PROVIDERS_INITIALIZING:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_PROVIDERS_INITIALIZING;
+            case STATE_STOPPED:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_STOPPED;
+            case STATE_INITIALIZING:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_INITIALIZING;
+            case STATE_UNCERTAIN:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_UNCERTAIN;
+            case STATE_CERTAIN:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_CERTAIN;
+            case STATE_FAILED:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_FAILED;
+            case STATE_DESTROYED:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_DESTROYED;
+            case STATE_UNKNOWN:
+            default:
+                return LocationTimeZoneManagerProto.CONTROLLER_STATE_UNKNOWN;
+        }
+    }
+
     private static void writeProviderStates(DualDumpOutputStream outputStream,
             List<LocationTimeZoneProvider.ProviderState> providerStates, String fieldName,
             long fieldId) {
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProviderController.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProviderController.java
index dbd3877..5d7730a 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProviderController.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProviderController.java
@@ -34,6 +34,7 @@
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.service.timezone.TimeZoneProviderEvent;
 import android.service.timezone.TimeZoneProviderSuggestion;
 import android.util.IndentingPrintWriter;
@@ -43,9 +44,15 @@
 import com.android.server.timezonedetector.ConfigurationInternal;
 import com.android.server.timezonedetector.Dumpable;
 import com.android.server.timezonedetector.GeolocationTimeZoneSuggestion;
+import com.android.server.timezonedetector.ReferenceWithHistory;
 import com.android.server.timezonedetector.location.ThreadingDomain.SingleRunnableQueue;
 
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import java.time.Duration;
+import java.util.ArrayList;
 import java.util.Objects;
 
 /**
@@ -93,6 +100,36 @@
  */
 class LocationTimeZoneProviderController implements Dumpable {
 
+    // String is used for easier logging / interpretation in bug reports Vs int.
+    @StringDef(prefix = "STATE_",
+            value = { STATE_UNKNOWN, STATE_PROVIDERS_INITIALIZING, STATE_STOPPED,
+                    STATE_INITIALIZING, STATE_UNCERTAIN, STATE_CERTAIN, STATE_FAILED,
+                    STATE_DESTROYED })
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
+    @interface State {}
+
+    /** The state used for an uninitialized controller. */
+    static final @State String STATE_UNKNOWN = "UNKNOWN";
+
+    /**
+     * A state used while the location time zone providers are initializing. Enables detection
+     * / avoidance of unwanted fail-over behavior before both providers are initialized.
+     */
+    static final @State String STATE_PROVIDERS_INITIALIZING = "PROVIDERS_INITIALIZING";
+    /** An inactive state: Detection is disabled. */
+    static final @State String STATE_STOPPED = "STOPPED";
+    /** An active state: No suggestion has yet been made. */
+    static final @State String STATE_INITIALIZING = "INITIALIZING";
+    /** An active state: The last suggestion was "uncertain". */
+    static final @State String STATE_UNCERTAIN = "UNCERTAIN";
+    /** An active state: The last suggestion was "certain". */
+    static final @State String STATE_CERTAIN = "CERTAIN";
+    /** An inactive state: The location time zone providers have failed. */
+    static final @State String STATE_FAILED = "FAILED";
+    /** An inactive state: The controller is destroyed. */
+    static final @State String STATE_DESTROYED = "DESTROYED";
+
     @NonNull private final ThreadingDomain mThreadingDomain;
     @NonNull private final Object mSharedLock;
     /**
@@ -102,6 +139,7 @@
      */
     @NonNull private final SingleRunnableQueue mUncertaintyTimeoutQueue;
 
+    @NonNull private final MetricsLogger mMetricsLogger;
     @NonNull private final LocationTimeZoneProvider mPrimaryProvider;
     @NonNull private final LocationTimeZoneProvider mSecondaryProvider;
 
@@ -117,10 +155,22 @@
     // Non-null after initialize()
     private Callback mCallback;
 
-    /** Indicates both providers have completed initialization. */
-    @GuardedBy("mSharedLock")
-    private boolean mProvidersInitialized;
+    /** Usually {@code false} but can be set to {@code true} to record state changes for testing. */
+    private final boolean mRecordStateChanges;
 
+    @GuardedBy("mSharedLock")
+    @NonNull
+    private final ArrayList<@State String> mRecordedStates = new ArrayList<>(0);
+
+    /**
+     * The current state. This is primarily for metrics / reporting of how long the controller
+     * spends active / inactive during a period. There is overlap with the provider states, but
+     * providers operate independently of each other, so this can help to understand how long the
+     * geo detection system overall was certain or uncertain when multiple providers might have been
+     * enabled concurrently.
+     */
+    @GuardedBy("mSharedLock")
+    private final ReferenceWithHistory<@State String> mState = new ReferenceWithHistory<>(10);
 
     /** Contains the last suggestion actually made, if there is one. */
     @GuardedBy("mSharedLock")
@@ -128,13 +178,21 @@
     private GeolocationTimeZoneSuggestion mLastSuggestion;
 
     LocationTimeZoneProviderController(@NonNull ThreadingDomain threadingDomain,
+            @NonNull MetricsLogger metricsLogger,
             @NonNull LocationTimeZoneProvider primaryProvider,
-            @NonNull LocationTimeZoneProvider secondaryProvider) {
+            @NonNull LocationTimeZoneProvider secondaryProvider,
+            boolean recordStateChanges) {
         mThreadingDomain = Objects.requireNonNull(threadingDomain);
         mSharedLock = threadingDomain.getLockObject();
         mUncertaintyTimeoutQueue = threadingDomain.createSingleRunnableQueue();
+        mMetricsLogger = Objects.requireNonNull(metricsLogger);
         mPrimaryProvider = Objects.requireNonNull(primaryProvider);
         mSecondaryProvider = Objects.requireNonNull(secondaryProvider);
+        mRecordStateChanges = recordStateChanges;
+
+        synchronized (mSharedLock) {
+            mState.set(STATE_UNKNOWN);
+        }
     }
 
     /**
@@ -152,9 +210,10 @@
 
             LocationTimeZoneProvider.ProviderListener providerListener =
                     LocationTimeZoneProviderController.this::onProviderStateChange;
+            setState(STATE_PROVIDERS_INITIALIZING);
             mPrimaryProvider.initialize(providerListener);
             mSecondaryProvider.initialize(providerListener);
-            mProvidersInitialized = true;
+            setState(STATE_STOPPED);
 
             alterProvidersStartedStateIfRequired(
                     null /* oldConfiguration */, mCurrentUserConfiguration);
@@ -209,8 +268,26 @@
 
         synchronized (mSharedLock) {
             stopProviders();
+
+            // Enter destroyed state.
             mPrimaryProvider.destroy();
             mSecondaryProvider.destroy();
+            setState(STATE_DESTROYED);
+        }
+    }
+
+    /**
+     * Updates {@link #mState} if needed, and performs all the record-keeping / callbacks associated
+     * with state changes.
+     */
+    @GuardedBy("mSharedLock")
+    private void setState(@State String state) {
+        if (!Objects.equals(mState.get(), state)) {
+            mState.set(state);
+            if (mRecordStateChanges) {
+                mRecordedStates.add(state);
+            }
+            mMetricsLogger.onStateChange(state);
         }
     }
 
@@ -226,11 +303,12 @@
         // suggestion must now be made to indicate the controller {does not / no longer has}
         // an opinion and will not be sending further updates (until at least the providers are
         // re-started).
-        if (mLastSuggestion != null && mLastSuggestion.getZoneIds() != null) {
+        if (Objects.equals(mState.get(), STATE_CERTAIN)) {
             GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
                     mEnvironment.elapsedRealtimeMillis(), "Providers are stopping");
-            makeSuggestion(suggestion);
+            makeSuggestion(suggestion, STATE_UNCERTAIN);
         }
+        setState(STATE_STOPPED);
     }
 
     @GuardedBy("mSharedLock")
@@ -300,6 +378,8 @@
         //    timeout started when the primary entered {started uncertain} should be cancelled.
 
         if (newGeoDetectionEnabled) {
+            setState(STATE_INITIALIZING);
+
             // Try to start the primary provider.
             tryStartProvider(mPrimaryProvider, newConfiguration);
 
@@ -314,13 +394,13 @@
                 ProviderState newSecondaryState = mSecondaryProvider.getCurrentState();
                 if (!newSecondaryState.isStarted()) {
                     // If both providers are {perm failed} then the controller immediately
-                    // becomes uncertain.
+                    // reports uncertain.
                     GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
                             mEnvironment.elapsedRealtimeMillis(),
                             "Providers are failed:"
                                     + " primary=" + mPrimaryProvider.getCurrentState()
                                     + " secondary=" + mPrimaryProvider.getCurrentState());
-                    makeSuggestion(suggestion);
+                    makeSuggestion(suggestion, STATE_FAILED);
                 }
             }
         } else {
@@ -368,7 +448,7 @@
             // Ignore provider state changes during initialization. e.g. if the primary provider
             // moves to PROVIDER_STATE_PERM_FAILED during initialization, the secondary will not
             // be ready to take over yet.
-            if (!mProvidersInitialized) {
+            if (Objects.equals(mState.get(), STATE_PROVIDERS_INITIALIZING)) {
                 warnLog("onProviderStateChange: Ignoring provider state change because both"
                         + " providers have not yet completed initialization."
                         + " providerState=" + providerState);
@@ -453,13 +533,13 @@
             cancelUncertaintyTimeout();
 
             // If both providers are now terminated, then a suggestion must be sent informing the
-            // time zone detector that there are no further updates coming in future.
+            // time zone detector that there are no further updates coming in the future.
             GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
                     mEnvironment.elapsedRealtimeMillis(),
                     "Both providers are terminated:"
                             + " primary=" + primaryCurrentState.provider
                             + ", secondary=" + secondaryCurrentState.provider);
-            makeSuggestion(suggestion);
+            makeSuggestion(suggestion, STATE_FAILED);
         }
     }
 
@@ -548,7 +628,7 @@
                 + ", providerEvent=" + providerEvent
                 + ", suggestionCreationTime=" + mEnvironment.elapsedRealtimeMillis();
         geoSuggestion.addDebugInfo(debugInfo);
-        makeSuggestion(geoSuggestion);
+        makeSuggestion(geoSuggestion, STATE_CERTAIN);
     }
 
     @Override
@@ -563,8 +643,14 @@
             ipw.println("providerInitializationTimeoutFuzz="
                     + mEnvironment.getProviderInitializationTimeoutFuzz());
             ipw.println("uncertaintyDelay=" + mEnvironment.getUncertaintyDelay());
+            ipw.println("mState=" + mState.get());
             ipw.println("mLastSuggestion=" + mLastSuggestion);
 
+            ipw.println("State history:");
+            ipw.increaseIndent(); // level 2
+            mState.dump(ipw);
+            ipw.decreaseIndent(); // level 2
+
             ipw.println("Primary Provider:");
             ipw.increaseIndent(); // level 2
             mPrimaryProvider.dump(ipw, args);
@@ -579,12 +665,17 @@
         }
     }
 
-    /** Sends an immediate suggestion, updating mLastSuggestion. */
+    /**
+     * Sends an immediate suggestion and enters a new state if needed. This method updates
+     * mLastSuggestion and changes mStateEnum / reports the new state for metrics.
+     */
     @GuardedBy("mSharedLock")
-    private void makeSuggestion(@NonNull GeolocationTimeZoneSuggestion suggestion) {
+    private void makeSuggestion(@NonNull GeolocationTimeZoneSuggestion suggestion,
+            @State String newState) {
         debugLog("makeSuggestion: suggestion=" + suggestion);
         mCallback.suggest(suggestion);
         mLastSuggestion = suggestion;
+        setState(newState);
     }
 
     /** Clears the uncertainty timeout. */
@@ -604,7 +695,7 @@
      * <p>This method schedules an "uncertainty" timeout (if one isn't already scheduled) to be
      * triggered later if nothing else preempts it. It can be preempted if the provider becomes
      * certain (or does anything else that calls {@link
-     * #makeSuggestion(GeolocationTimeZoneSuggestion)}) within {@link
+     * #makeSuggestion(GeolocationTimeZoneSuggestion, String)}) within {@link
      * Environment#getUncertaintyDelay()}. Preemption causes the scheduled
      * "uncertainty" timeout to be cancelled. If the provider repeatedly sends uncertainty events
      * within the uncertainty delay period, those events are effectively ignored (i.e. the timeout
@@ -666,7 +757,7 @@
                             + Duration.ofMillis(afterUncertaintyTimeoutElapsedMillis)
                             + ", uncertaintyDelay=" + uncertaintyDelay
             );
-            makeSuggestion(suggestion);
+            makeSuggestion(suggestion, STATE_UNCERTAIN);
         }
     }
 
@@ -682,12 +773,13 @@
     }
 
     /**
-     * Clears recorded provider state changes (for use during tests).
+     * Clears recorded controller and provider state changes (for use during tests).
      */
-    void clearRecordedProviderStates() {
+    void clearRecordedStates() {
         mThreadingDomain.assertCurrentThread();
 
         synchronized (mSharedLock) {
+            mRecordedStates.clear();
             mPrimaryProvider.clearRecordedStates();
             mSecondaryProvider.clearRecordedStates();
         }
@@ -706,7 +798,9 @@
             if (mLastSuggestion != null) {
                 builder.setLastSuggestion(mLastSuggestion);
             }
-            builder.setPrimaryProviderStateChanges(mPrimaryProvider.getRecordedStates())
+            builder.setControllerState(mState.get())
+                    .setStateChanges(mRecordedStates)
+                    .setPrimaryProviderStateChanges(mPrimaryProvider.getRecordedStates())
                     .setSecondaryProviderStateChanges(mSecondaryProvider.getRecordedStates());
             return builder.build();
         }
@@ -782,4 +876,12 @@
          */
         abstract void suggest(@NonNull GeolocationTimeZoneSuggestion suggestion);
     }
+
+    /**
+     * Used by {@link LocationTimeZoneProviderController} to record events for metrics / telemetry.
+     */
+    interface MetricsLogger {
+        /** Called when the controller's state changes. */
+        void onStateChange(@State String stateEnum);
+    }
 }
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 5d40c23..9717201 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -341,7 +341,7 @@
             if (!isEffectValid(effect)) {
                 return false;
             }
-            attrs = fixupVibrationAttributes(attrs);
+            attrs = fixupVibrationAttributes(attrs, effect);
             synchronized (mLock) {
                 SparseArray<PrebakedSegment> effects = fixupAlwaysOnEffectsLocked(effect);
                 if (effects == null) {
@@ -385,7 +385,7 @@
             if (!isEffectValid(effect)) {
                 return null;
             }
-            attrs = fixupVibrationAttributes(attrs);
+            attrs = fixupVibrationAttributes(attrs, effect);
             Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs,
                     uid, opPkg, reason);
             fillVibrationFallbacks(vib, effect);
@@ -895,21 +895,32 @@
      * Return new {@link VibrationAttributes} that only applies flags that this user has permissions
      * to use.
      */
-    private VibrationAttributes fixupVibrationAttributes(@Nullable VibrationAttributes attrs) {
+    @NonNull
+    private VibrationAttributes fixupVibrationAttributes(@Nullable VibrationAttributes attrs,
+            CombinedVibration effect) {
         if (attrs == null) {
             attrs = DEFAULT_ATTRIBUTES;
         }
+        int usage = attrs.getUsage();
+        if ((usage == VibrationAttributes.USAGE_UNKNOWN) && effect.isHapticFeedbackCandidate()) {
+            usage = VibrationAttributes.USAGE_TOUCH;
+        }
+        int flags = attrs.getFlags();
         if (attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)) {
             if (!(hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
                     || hasPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
                     || hasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING))) {
-                final int flags = attrs.getFlags()
-                        & ~VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
-                attrs = new VibrationAttributes.Builder(attrs)
-                        .setFlags(flags, attrs.getFlags()).build();
+                // Remove bypass policy flag from attributes if the app does not have permissions.
+                flags &= ~VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
             }
         }
-        return attrs;
+        if ((usage == attrs.getUsage()) && (flags == attrs.getFlags())) {
+            return attrs;
+        }
+        return new VibrationAttributes.Builder(attrs)
+                .setUsage(usage)
+                .setFlags(flags, attrs.getFlags())
+                .build();
     }
 
     @GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 73a783e..bb7434d 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2784,8 +2784,8 @@
         // If it exist, we need to reparent target root task from TDA to launch root task.
         final TaskDisplayArea tda = mTargetRootTask.getDisplayArea();
         final Task launchRootTask = tda.getLaunchRootTask(mTargetRootTask.getWindowingMode(),
-                mTargetRootTask.getActivityType(), null /** options */,
-                mSourceRootTask, 0 /** launchFlags */);
+                mTargetRootTask.getActivityType(), null /** options */, mSourceRootTask,
+                mLaunchFlags);
         // If target root task is created by organizer, let organizer handle reparent itself.
         if (!mTargetRootTask.mCreatedByOrganizer && launchRootTask != null
                 && launchRootTask != mTargetRootTask) {
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index adf892a..5dc048b 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -28,6 +28,7 @@
 
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
@@ -150,7 +151,7 @@
             PackageInfo packageInfo, @UserIdInt int userId, int uid) {
         when(mPackageManagerInternal.getPackageInfo(
                         eq(CROSS_PROFILE_APP_PACKAGE_NAME),
-                        /* flags= */ anyInt(),
+                        /* flags= */ anyLong(),
                         /* filterCallingUid= */ anyInt(),
                         eq(userId)))
                 .thenReturn(packageInfo);
@@ -469,7 +470,7 @@
     private void mockUninstallCrossProfileAppFromWorkProfile() {
         when(mPackageManagerInternal.getPackageInfo(
                         eq(CROSS_PROFILE_APP_PACKAGE_NAME),
-                        /* flags= */ anyInt(),
+                        /* flags= */ anyLong(),
                         /* filterCallingUid= */ anyInt(),
                         eq(WORK_PROFILE_USER_ID)))
                 .thenReturn(null);
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationValidIntentTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationValidIntentTest.kt
index 98634b2..ac6b679 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationValidIntentTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationValidIntentTest.kt
@@ -120,7 +120,7 @@
     @Test
     fun verify() {
         val flags = if (params.matchDefaultOnly) PackageManager.MATCH_DEFAULT_ONLY else 0
-        assertThat(DomainVerificationUtils.isDomainVerificationIntent(params.intent, flags))
-            .isEqualTo(params.expected)
+        assertThat(DomainVerificationUtils.isDomainVerificationIntent(params.intent,
+            flags.toLong())).isEqualTo(params.expected)
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index a9099ae..5885470 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -2961,7 +2961,7 @@
     private void registerAppIds(String[] packages, Integer[] ids) {
         assertEquals(packages.length, ids.length);
 
-        when(mPackageManagerInternal.getPackageUid(anyString(), anyInt(), anyInt())).thenAnswer(
+        when(mPackageManagerInternal.getPackageUid(anyString(), anyLong(), anyInt())).thenAnswer(
                 invocation -> {
                     final String pkg = invocation.getArgument(0);
                     final int index = ArrayUtils.indexOf(packages, pkg);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
index b2847ce..783971a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/PendingIntentControllerTest.java
@@ -22,6 +22,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -80,7 +81,7 @@
         doReturn(mActivityManagerInternal).when(
                 () -> LocalServices.getService(ActivityManagerInternal.class));
         doReturn(mIPackageManager).when(() -> AppGlobals.getPackageManager());
-        when(mIPackageManager.getPackageUid(eq(TEST_PACKAGE_NAME), anyInt(), anyInt())).thenReturn(
+        when(mIPackageManager.getPackageUid(eq(TEST_PACKAGE_NAME), anyLong(), anyInt())).thenReturn(
                 TEST_CALLING_UID);
         ActivityManagerConstants constants = mock(ActivityManagerConstants.class);
         constants.PENDINGINTENT_WARNING_THRESHOLD = 2000;
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 63416c9..0e5640a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -47,6 +47,7 @@
 import com.android.dx.mockito.inline.extended.ExtendedMockito.any
 import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean
 import com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt
+import com.android.dx.mockito.inline.extended.ExtendedMockito.anyLong
 import com.android.dx.mockito.inline.extended.ExtendedMockito.anyString
 import com.android.dx.mockito.inline.extended.ExtendedMockito.argThat
 import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
@@ -617,7 +618,7 @@
     private fun mockQueryActivities(action: String, vararg activities: ActivityInfo) {
         whenever(mocks.componentResolver.queryActivities(
                 argThat { intent: Intent? -> intent != null && (action == intent.action) },
-                nullable(), anyInt(), anyInt())) {
+                nullable(), anyLong(), anyInt())) {
             ArrayList(activities.asList().map { info: ActivityInfo? ->
                 ResolveInfo().apply { activityInfo = info }
             })
@@ -627,7 +628,7 @@
     private fun mockQueryServices(action: String, vararg services: ServiceInfo) {
         whenever(mocks.componentResolver.queryServices(
                 argThat { intent: Intent? -> intent != null && (action == intent.action) },
-                nullable(), anyInt(), anyInt())) {
+                nullable(), anyLong(), anyInt())) {
             ArrayList(services.asList().map { info ->
                 ResolveInfo().apply { serviceInfo = info }
             })
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
index fe23c14..9666758 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -41,6 +41,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -316,14 +317,14 @@
         final int lastUserId = 5;
         final ServiceInfo pi = mIpm.getServiceInfo(sDefaultWallpaperComponent,
                 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS, 0);
-        doReturn(pi).when(mIpm).getServiceInfo(any(), anyInt(), anyInt());
+        doReturn(pi).when(mIpm).getServiceInfo(any(), anyLong(), anyInt());
 
         final Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
         final ParceledListSlice ris =
                 mIpm.queryIntentServices(intent,
                         intent.resolveTypeIfNeeded(sContext.getContentResolver()),
                         PackageManager.GET_META_DATA, 0);
-        doReturn(ris).when(mIpm).queryIntentServices(any(), any(), anyInt(), anyInt());
+        doReturn(ris).when(mIpm).queryIntentServices(any(), any(), anyLong(), anyInt());
         doReturn(PackageManager.PERMISSION_GRANTED).when(mIpm).checkPermission(
                 eq(android.Manifest.permission.AMBIENT_WALLPAPER), any(), anyInt());
 
@@ -348,7 +349,7 @@
         final int lastUserId = 5;
         final ServiceInfo pi = mIpm.getServiceInfo(sDefaultWallpaperComponent,
                 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS, 0);
-        doReturn(pi).when(mIpm).getServiceInfo(any(), anyInt(), anyInt());
+        doReturn(pi).when(mIpm).getServiceInfo(any(), anyLong(), anyInt());
 
         final Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
         final ParceledListSlice ris =
@@ -362,7 +363,7 @@
             mService.switchUser(userId, null);
             verifyLastWallpaperData(userId, sImageWallpaperComponentName);
             // Simulate user unlocked
-            doReturn(ris).when(mIpm).queryIntentServices(any(), any(), anyInt(), eq(userId));
+            doReturn(ris).when(mIpm).queryIntentServices(any(), any(), anyLong(), eq(userId));
             mService.onUnlockUser(userId);
             verifyLastWallpaperData(userId, sDefaultWallpaperComponent);
             verifyCurrentSystemData(userId);
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
index 1c49e6e..e40f543 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -29,7 +29,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.intThat;
+import static org.mockito.ArgumentMatchers.longThat;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -135,7 +135,7 @@
         packages.add(makePackageInfo(PACKAGE_NAME_2));
         packages.add(makePackageInfo(PACKAGE_NAME_3));
         doReturn(new ParceledListSlice<>(packages)).when(mIPackageManager).getInstalledPackages(
-                intThat(arg -> (arg & MATCH_ANY_USER) != 0), anyInt());
+                longThat(arg -> (arg & MATCH_ANY_USER) != 0), anyInt());
         mAppHibernationService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
 
         UserInfo userInfo = addUser(USER_ID_1);
@@ -412,7 +412,7 @@
         UserInfo userInfo = new UserInfo(userId, "user_" + userId, 0 /* flags */);
         mUserInfos.add(userInfo);
         doReturn(new ParceledListSlice<>(userPackages)).when(mIPackageManager)
-                .getInstalledPackages(intThat(arg -> (arg & MATCH_ANY_USER) == 0), eq(userId));
+                .getInstalledPackages(longThat(arg -> (arg & MATCH_ANY_USER) == 0), eq(userId));
         return userInfo;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 2777bdf..3c809f9 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -1735,11 +1735,11 @@
         pi.applicationInfo.flags = flags;
         doReturn(pi).when(getServices().ipackageManager).getPackageInfo(
                 eq(packageName),
-                anyInt(),
+                anyLong(),
                 eq(userId));
         doReturn(pi.applicationInfo).when(getServices().ipackageManager).getApplicationInfo(
                 eq(packageName),
-                anyInt(),
+                anyLong(),
                 eq(userId));
         doReturn(true).when(getServices().ipackageManager).isPackageAvailable(packageName, userId);
         // Setup application UID with the PackageManager
@@ -4708,11 +4708,11 @@
         // Ensure packages are *not* flagged as test_only.
         doReturn(new ApplicationInfo()).when(getServices().ipackageManager).getApplicationInfo(
                 eq(admin1.getPackageName()),
-                anyInt(),
+                anyLong(),
                 eq(CALLER_USER_HANDLE));
         doReturn(new ApplicationInfo()).when(getServices().ipackageManager).getApplicationInfo(
                 eq(admin2.getPackageName()),
-                anyInt(),
+                anyLong(),
                 eq(CALLER_USER_HANDLE));
 
         // Initial state is disabled.
@@ -7078,7 +7078,7 @@
 
         doReturn(ai).when(getServices().ipackageManager).getApplicationInfo(
                 eq(admin1.getPackageName()),
-                anyInt(),
+                anyLong(),
                 eq(CALLER_USER_HANDLE));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index fe0df58..b8824c3 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -21,7 +21,6 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.when;
@@ -221,7 +220,7 @@
 
         doReturn(ai).when(mServices.ipackageManager).getApplicationInfo(
                 eq(admin.getPackageName()),
-                anyInt(),
+                anyLong(),
                 eq(UserHandle.getUserId(packageUid)));
 
         // Set up queryBroadcastReceivers().
@@ -248,7 +247,7 @@
 
         doReturn(aci).when(mServices.ipackageManager).getReceiverInfo(
                 eq(admin),
-                anyInt(),
+                anyLong(),
                 eq(UserHandle.getUserId(packageUid)));
 
         doReturn(new String[] {admin.getPackageName()}).when(mServices.ipackageManager)
diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
index b3a513f..ddc58b2 100644
--- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
@@ -110,7 +111,7 @@
     @Test(expected = SecurityException.class)
     public void testSetApplicationLocales_arbitraryAppWithoutPermissions_fails() throws Exception {
         doReturn(DEFAULT_UID)
-                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyInt(), anyInt());
+                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
         setUpFailingPermissionCheckFor(Manifest.permission.CHANGE_CONFIGURATION);
 
         try {
@@ -153,7 +154,7 @@
     @Test
     public void testSetApplicationLocales_arbitraryAppWithPermission_succeeds() throws Exception {
         doReturn(DEFAULT_UID)
-                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyInt(), anyInt());
+                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
         // if package is not owned by the caller, the calling app should have the following
         //   permission. We will mock this to succeed to imitate that.
         setUpPassingPermissionCheckFor(Manifest.permission.CHANGE_CONFIGURATION);
@@ -168,7 +169,7 @@
     @Test
     public void testSetApplicationLocales_callerOwnsPackage_succeeds() throws Exception {
         doReturn(Binder.getCallingUid())
-                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyInt(), anyInt());
+                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
 
         mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID,
                 DEFAULT_LOCALES);
@@ -179,7 +180,7 @@
     @Test(expected = IllegalArgumentException.class)
     public void testSetApplicationLocales_invalidPackageOrUserId_fails() throws Exception {
         doReturn(INVALID_UID)
-                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyInt(), anyInt());
+                .when(mMockPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
         try {
             mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID,
                     LocaleList.getEmptyLocaleList());
@@ -192,7 +193,7 @@
     @Test(expected = SecurityException.class)
     public void testGetApplicationLocales_arbitraryAppWithoutPermission_fails() throws Exception {
         doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
-                .getPackageUid(anyString(), anyInt(), anyInt());
+                .getPackageUid(anyString(), anyLong(), anyInt());
         setUpFailingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
 
         try {
@@ -210,7 +211,7 @@
             throws Exception {
         // any valid app calling for its own package or having appropriate permission
         doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
-                .getPackageUid(anyString(), anyInt(), anyInt());
+                .getPackageUid(anyString(), anyLong(), anyInt());
         setUpPassingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
         doReturn(null)
                 .when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
@@ -225,7 +226,7 @@
     public void testGetApplicationLocales_appSpecificLocalesAbsent_returnsEmptyList()
             throws Exception {
         doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
-                .getPackageUid(anyString(), anyInt(), anyInt());
+                .getPackageUid(anyString(), anyLong(), anyInt());
         setUpPassingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
         doReturn(new PackageConfig(/* nightMode = */ 0, /* locales = */ null))
                 .when(mMockActivityTaskManager).getApplicationConfig(any(), anyInt());
@@ -240,7 +241,7 @@
     public void testGetApplicationLocales_callerOwnsAppAndConfigPresent_returnsLocales()
             throws Exception {
         doReturn(Binder.getCallingUid()).when(mMockPackageManagerInternal)
-                .getPackageUid(anyString(), anyInt(), anyInt());
+                .getPackageUid(anyString(), anyLong(), anyInt());
         doReturn(new PackageConfig(/* nightMode = */ 0, DEFAULT_LOCALES))
                 .when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
 
@@ -254,7 +255,7 @@
     public void testGetApplicationLocales_arbitraryCallerWithPermissions_returnsLocales()
             throws Exception {
         doReturn(DEFAULT_UID).when(mMockPackageManagerInternal)
-                .getPackageUid(anyString(), anyInt(), anyInt());
+                .getPackageUid(anyString(), anyLong(), anyInt());
         setUpPassingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
         doReturn(new PackageConfig(/* nightMode = */ 0, DEFAULT_LOCALES))
                 .when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index f45c869..3722ba4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
@@ -2357,7 +2358,7 @@
 
     protected void prepareIntentActivities(ComponentName cn) {
         when(mMockPackageManagerInternal.queryIntentActivities(
-                anyOrNull(Intent.class), anyStringOrNull(), anyInt(), anyInt(), anyInt()))
+                anyOrNull(Intent.class), anyStringOrNull(), anyLong(), anyInt(), anyInt()))
                 .thenReturn(Collections.singletonList(
                         ri(cn.getPackageName(), cn.getClassName(), false, 0)));
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/BundleUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/BundleUtilsTest.java
index 764c504..6245f82 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BundleUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BundleUtilsTest.java
@@ -22,8 +22,9 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.os.Bundle;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.BundleUtils;
@@ -35,6 +36,7 @@
  * Build/Install/Run:
  * atest com.android.server.pm.BundleUtilsTest
  */
+@Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class BundleUtilsTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java b/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java
index b228c83..54ab133 100644
--- a/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/CompatibilityModeTest.java
@@ -32,6 +32,7 @@
 import android.content.pm.parsing.PackageInfoWithoutStateUtils;
 import android.content.pm.parsing.ParsingPackageUtils;
 import android.os.Build;
+import android.platform.test.annotations.Presubmit;
 
 import com.android.server.pm.parsing.pkg.PackageImpl;
 import com.android.server.pm.pkg.PackageUserStateImpl;
@@ -40,6 +41,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
+@Presubmit
 public class CompatibilityModeTest {
 
     private boolean mCompatibilityModeEnabled;;
diff --git a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
index e811c1f..3cb5d5f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
@@ -3,9 +3,10 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
@@ -14,7 +15,6 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-
 import static org.testng.Assert.assertThrows;
 
 import android.Manifest;
@@ -581,7 +581,7 @@
     private void mockAppsInstalled(String packageName, int user, boolean installed) {
         when(mPackageManagerInternal.getPackageInfo(
                 eq(packageName),
-                anyInt(),
+                anyLong(),
                 anyInt(),
                 eq(user)))
                 .thenReturn(installed ? createInstalledPackageInfo() : null);
@@ -604,7 +604,7 @@
         mActivityInfo = activityInfo;
 
         when(mPackageManagerInternal.queryIntentActivities(
-                any(Intent.class), nullable(String.class), anyInt(), anyInt(), anyInt()))
+                any(Intent.class), nullable(String.class), anyLong(), anyInt(), anyInt()))
                 .thenReturn(Collections.singletonList(resolveInfo));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
index 9631863..6b6d84a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
@@ -20,6 +20,7 @@
 import static android.content.pm.parsing.ParsingPackageUtils.parsePublicKey;
 
 import android.content.pm.Signature;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -33,6 +34,7 @@
 import java.security.PublicKey;
 import java.security.cert.CertificateException;
 
+@Presubmit
 public class KeySetManagerServiceTest extends AndroidTestCase {
 
     private WatchedArrayMap<String, PackageSetting> mPackagesMap;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java
index 6a9ef8a..9ea7907 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.pm.ModuleInfo;
 import android.content.pm.PackageManager;
+import android.platform.test.annotations.Presubmit;
 import android.test.InstrumentationTestCase;
 
 import com.android.frameworks.servicestests.R;
@@ -30,6 +31,7 @@
 import java.util.Collections;
 import java.util.List;
 
+@Presubmit
 public class ModuleInfoProviderTest extends InstrumentationTestCase {
 
     @Mock private ApexManager mApexManager;
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 5e2da20..b81a4ef 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -37,6 +37,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.Postsubmit;
 import android.util.SparseArray;
 
 import androidx.test.InstrumentationRegistry;
@@ -69,6 +70,7 @@
 // atest PackageManagerServiceTest
 // runtest -c com.android.server.pm.PackageManagerServiceTest frameworks-services
 // bit FrameworksServicesTests:com.android.server.pm.PackageManagerServiceTest
+@Postsubmit
 @RunWith(AndroidJUnit4.class)
 public class PackageManagerServiceTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index ab37e9b..a9a3469 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -47,6 +47,7 @@
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Log;
@@ -91,6 +92,7 @@
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PackageManagerSettingsTests {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
index b6d4b31..7e4474f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.pm.Signature;
 import android.content.pm.SigningDetails;
+import android.platform.test.annotations.Presubmit;
 import android.util.TypedXmlPullParser;
 import android.util.Xml;
 
@@ -44,6 +45,7 @@
 import java.util.Map;
 import java.util.Set;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class PackageSignaturesTest {
     private static final String TEST_RESOURCES_FOLDER = "PackageSignaturesTest";
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
index c9f3cb2..828d419c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
@@ -28,6 +28,7 @@
 import android.content.pm.SuspendDialogInfo;
 import android.content.pm.overlay.OverlayPaths;
 import android.os.PersistableBundle;
+import android.platform.test.annotations.Presubmit;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
@@ -41,6 +42,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PackageUserStateTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
index 1fff4f0..ecf7803 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
@@ -18,8 +18,10 @@
 
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 
+@Presubmit
 public class PackageVerificationStateTest extends AndroidTestCase {
     private static final int REQUIRED_UID = 1948;
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/RestrictionsSetTest.java b/services/tests/servicestests/src/com/android/server/pm/RestrictionsSetTest.java
index b73c9ea..e7adf7b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/RestrictionsSetTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/RestrictionsSetTest.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -37,6 +38,7 @@
 import java.util.List;
 
 /** Test for {@link RestrictionsSet}. */
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class RestrictionsSetTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index ec5228f..32a88bd 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -95,13 +95,15 @@
 import android.os.Looper;
 import android.os.Process;
 import android.os.UserHandle;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.TypedXmlPullParser;
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.frameworks.servicestests.R;
 import com.android.server.pm.ShortcutService.ConfigConstants;
 import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
@@ -135,6 +137,7 @@
  adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 \
  -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
index e92c849..57ada9b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
@@ -15,10 +15,13 @@
  */
 package com.android.server.pm;
 
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils
-        .assertExpectException;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.LauncherActivityInfo;
@@ -26,9 +29,9 @@
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.os.Process;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
 
-import static org.mockito.Mockito.*;
+import androidx.test.filters.SmallTest;
 
 /**
  * Tests for {@link ShortcutManager#createShortcutResultIntent(ShortcutInfo)} and relevant APIs.
@@ -39,6 +42,7 @@
  adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest10 \
  -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
index c8a4052..98fa2d6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
@@ -30,6 +30,7 @@
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.ShortcutInfo;
 import android.os.test.TestLooper;
+import android.platform.test.annotations.Presubmit;
 
 import com.android.server.pm.ShortcutService.ConfigConstants;
 
@@ -42,6 +43,7 @@
  *
  atest -c com.android.server.pm.ShortcutManagerTest11
  */
+@Presubmit
 public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
 
     private static final ShortcutQuery QUERY_MATCH_ALL = createShortcutQuery(
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 90a1277..408d2c5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -43,8 +43,10 @@
 import android.net.Uri;
 import android.os.PersistableBundle;
 import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
 import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.frameworks.servicestests.R;
 import com.android.server.pm.ShortcutUser.PackageWithUser;
@@ -64,6 +66,7 @@
  adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 \
  -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
     // ShortcutInfo tests
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
index ba26f79..43e527c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
@@ -21,7 +21,9 @@
 
 import android.content.ComponentName;
 import android.content.pm.ShortcutInfo;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.frameworks.servicestests.R;
 import com.android.server.pm.ShortcutService.ConfigConstants;
@@ -31,6 +33,7 @@
 /**
  * Tests related to shortcut rank auto-adjustment.
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java
index 7546c43..11a2a8a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java
@@ -24,15 +24,17 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.PersistableBundle;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
 import android.util.Xml;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+@Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class ShortcutManagerTest4 extends BaseShortcutManagerTest {
@@ -134,4 +136,4 @@
                     });
         });
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java
index 203b2ca..400d3a8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java
@@ -25,7 +25,9 @@
 import android.content.pm.ShortcutServiceInternal;
 import android.content.res.XmlResourceParser;
 import android.os.Looper;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.server.LocalServices;
 
@@ -38,6 +40,7 @@
  * All the tests here actually talks to the real IPackageManager, so we can't test complicated
  * cases.  Instead we just make sure they all work reasonably without at least crashing.
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest5 extends BaseShortcutManagerTest {
     private ShortcutService mShortcutService;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java
index 63df4bc..6c10bfd 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java
@@ -15,12 +15,15 @@
  */
 package com.android.server.pm;
 
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
 
 /**
  * Tests for {@link ShortcutService#hasShortcutHostPermissionInner}, which includes
  * {@link ShortcutService#getDefaultLauncher}.
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest6 extends BaseShortcutManagerTest {
     public void testHasShortcutHostPermissionInner_with3pLauncher_complicated() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
index b21b049..b2fd8aa 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
@@ -33,7 +33,9 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.frameworks.servicestests.R;
 import com.android.server.pm.ShortcutService.ConfigConstants;
@@ -48,6 +50,7 @@
  *
  * Launcher related commands are tested in
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
index 58e00f2..2293808 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
@@ -40,11 +40,13 @@
 import android.content.pm.ShortcutManager;
 import android.graphics.drawable.Icon;
 import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
 import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import android.util.Pair;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.frameworks.servicestests.R;
 
 import org.mockito.ArgumentCaptor;
@@ -63,6 +65,7 @@
  * - Reading icons from requested shortcuts.
  * - Invalid pre-approved token.
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
     private ShortcutRequestPinProcessor mProcessor;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
index 55b4b93..a47a8df 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
@@ -32,7 +32,9 @@
 import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.PinItemRequest;
 import android.os.UserHandle;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
 
 import org.mockito.ArgumentCaptor;
 
@@ -46,6 +48,7 @@
  adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest9 \
  -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  */
+@Presubmit
 @SmallTest
 public class ShortcutManagerTest9 extends BaseShortcutManagerTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
index 826a8d4..4af91c6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertNull;
 
 import android.content.pm.SuspendDialogInfo;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -31,6 +32,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SuspendDialogInfoTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
new file mode 100644
index 0000000..85a73bb
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
@@ -0,0 +1,41 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.pm."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
+    }
+  ],
+  "postsubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.pm."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Postsubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
index 7916bd3..a4afe09 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
@@ -24,6 +24,7 @@
 import android.content.pm.UserInfo;
 import android.os.RemoteException;
 import android.os.UserManager;
+import android.platform.test.annotations.Postsubmit;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
@@ -42,6 +43,7 @@
  * To run the test:
  * bit FrameworksServicesTests:com.android.server.pm.UserLifecycleStressTest
  */
+@Postsubmit
 @RunWith(AndroidJUnit4.class)
 @LargeTest
 public class UserLifecycleStressTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
index 35c513f..fdf94be 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
@@ -27,6 +27,7 @@
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.Postsubmit;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.MediumTest;
@@ -48,6 +49,7 @@
  * runtest -c com.android.server.pm.UserManagerServiceCreateProfileTest frameworks-services
  * </pre>
  */
+@Postsubmit
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class UserManagerServiceCreateProfileTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java
index b0423bf..1f4c9f8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceIdRecyclingTest.java
@@ -23,6 +23,7 @@
 import android.app.PropertyInvalidatedCache;
 import android.content.pm.UserInfo;
 import android.os.Looper;
+import android.platform.test.annotations.Postsubmit;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.MediumTest;
@@ -45,6 +46,7 @@
  * -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  * </pre>
  */
+@Postsubmit
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class UserManagerServiceIdRecyclingTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 6c1c019..34b40c7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -22,18 +22,20 @@
 import android.os.Parcelable;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.Postsubmit;
 import android.support.test.uiautomator.UiDevice;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 import android.util.AtomicFile;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 
+@Postsubmit
 @SmallTest
 public class UserManagerServiceTest extends AndroidTestCase {
     private static String[] STRING_ARRAY = new String[] {"<tag", "<![CDATA["};
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index dfc25e0..92fddc7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -46,6 +46,7 @@
 import android.os.Parcel;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
 import android.text.TextUtils;
 
 import androidx.test.InstrumentationRegistry;
@@ -69,6 +70,7 @@
  * runtest -c com.android.server.pm.UserManagerServiceUserInfoTest frameworks-services
  * </pre>
  */
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class UserManagerServiceUserInfoTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
index f1acc66..971b036 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
@@ -39,6 +39,7 @@
 import android.content.res.XmlResourceParser;
 import android.os.Bundle;
 import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
 import android.util.ArrayMap;
 
 import androidx.test.InstrumentationRegistry;
@@ -58,6 +59,7 @@
  *
  * <p>Run with: atest UserManagerServiceUserTypeTest
  */
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class UserManagerServiceUserTypeTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index ea0c073..cf6165f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -35,14 +35,15 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.Postsubmit;
 import android.provider.Settings;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Slog;
 
 import androidx.annotation.Nullable;
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.google.common.collect.Range;
@@ -63,6 +64,7 @@
 import javax.annotation.concurrent.GuardedBy;
 
 /** Test {@link UserManager} functionality. */
+@Postsubmit
 @RunWith(AndroidJUnit4.class)
 public final class UserManagerTest {
     // Taken from UserManagerService
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
index ddf0cd0..07a5303 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -22,10 +22,12 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.SparseArray;
 
+import androidx.test.filters.SmallTest;
+
 /**
  * Tests for {@link com.android.server.pm.UserRestrictionsUtils}.
  *
@@ -37,6 +39,7 @@
      -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  * </pre>
  */
+@Presubmit
 @SmallTest
 public class UserRestrictionsUtilsTest extends AndroidTestCase {
     public void testNonNull() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
index b11bb85..ba7a103 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
@@ -43,6 +43,7 @@
 import android.os.Looper;
 import android.os.SystemProperties;
 import android.os.UserManager;
+import android.platform.test.annotations.Postsubmit;
 import android.support.test.uiautomator.UiDevice;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -76,6 +77,7 @@
  * atest com.android.server.pm.UserSystemPackageInstallerTest
  * </pre>
  */
+@Postsubmit
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class UserSystemPackageInstallerTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java b/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
index b2c3002..95af1e1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
@@ -20,6 +20,7 @@
 
 import android.content.ComponentName;
 import android.content.IntentFilter;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 
@@ -29,6 +30,7 @@
 
 import java.util.Iterator;
 
+@Presubmit
 @SmallTest
 public class WatchedIntentHandlingTest {
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
index fdb6e9f5..a16ecb1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
@@ -18,6 +18,8 @@
 
 import static org.mockito.Mockito.inOrder;
 
+import android.platform.test.annotations.Presubmit;
+
 import com.android.internal.art.ArtStatsLog;
 import com.android.server.pm.dex.ArtStatsLogUtils.ArtStatsLogger;
 
@@ -44,6 +46,7 @@
  *
  * Run with "atest ArtStatsLogUtilsTest".
  */
+@Presubmit
 @RunWith(JUnit4.class)
 public final class ArtStatsLogUtilsTest {
     private static final String TAG = ArtStatsLogUtilsTest.class.getSimpleName();
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
index 2a7a2ff..b7b55ba 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
@@ -30,6 +30,7 @@
 import android.content.pm.parsing.result.ParseResult;
 import android.content.pm.parsing.result.ParseTypeImpl;
 import android.os.FileUtils;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -61,6 +62,7 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+@Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DexMetadataHelperTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
index bc84e35..d5893c8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
@@ -23,6 +23,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.Presubmit;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -32,6 +34,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class DexoptOptionsTests {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
index 34cefec..1dcb0b7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
@@ -24,6 +24,7 @@
 
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.parsing.ParsingPackage;
+import android.platform.test.annotations.Presubmit;
 import android.util.SparseArray;
 
 import androidx.test.filters.SmallTest;
@@ -46,6 +47,7 @@
 import java.util.Collections;
 import java.util.List;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class DexoptUtilsTest {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java
index 7992ba3..d55f967 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java
@@ -31,6 +31,7 @@
 import android.content.pm.PackageInfo;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -51,6 +52,7 @@
 import org.mockito.quality.Strictness;
 import org.mockito.stubbing.Stubber;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class DynamicCodeLoggerTests {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
index 3450710..c98e7c3 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
@@ -28,6 +28,7 @@
 import static org.junit.Assert.fail;
 
 import android.os.Build;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -49,6 +50,7 @@
 import java.util.Map;
 import java.util.Set;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PackageDexUsageTests {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDynamicCodeLoadingTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDynamicCodeLoadingTests.java
index f4cdc8c..e075379 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDynamicCodeLoadingTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDynamicCodeLoadingTests.java
@@ -30,6 +30,8 @@
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import android.platform.test.annotations.Presubmit;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -50,6 +52,7 @@
 import java.util.Objects;
 import java.util.Set;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PackageDynamicCodeLoadingTests {
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
index 0ae5ecb..122661e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
@@ -147,8 +147,8 @@
             flags: Int = 0,
             userId: Int = 0
         ): ApplicationInfo? {
-            return PackageInfoUtils.generateApplicationInfo(pkg, flags, dummyUserState, userId,
-                    mockPkgSetting(pkg))
+            return PackageInfoUtils.generateApplicationInfo(pkg, flags.toLong(), dummyUserState,
+                userId, mockPkgSetting(pkg))
         }
 
         fun newAppInfoWithoutState(
@@ -156,8 +156,8 @@
             flags: Int = 0,
             userId: Int = 0
         ): ApplicationInfo? {
-            return PackageInfoUtils.generateApplicationInfo(pkg, flags, dummyUserState, userId,
-                    mockPkgSetting(pkg))
+            return PackageInfoUtils.generateApplicationInfo(pkg, flags.toLong(), dummyUserState,
+                userId, mockPkgSetting(pkg))
         }
 
         fun oldPackageInfo(pkg: PackageParser.Package, flags: Int = 0): PackageInfo? {
@@ -166,7 +166,7 @@
         }
 
         fun newPackageInfo(pkg: AndroidPackage, flags: Int = 0): PackageInfo? {
-            return PackageInfoUtils.generate(pkg, intArrayOf(), flags, 5, 6, emptySet(),
+            return PackageInfoUtils.generate(pkg, intArrayOf(), flags.toLong(), 5, 6, emptySet(),
                     dummyUserState, 0, mockPkgSetting(pkg))
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt
index c4aa862..f530421 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt
@@ -21,6 +21,7 @@
 import android.content.pm.parsing.ParsingPackage
 import android.content.pm.parsing.ParsingPackageUtils
 import android.content.pm.parsing.result.ParseResult
+import android.platform.test.annotations.Presubmit
 import androidx.test.InstrumentationRegistry
 import com.android.frameworks.servicestests.R
 import com.google.common.truth.Truth.assertThat
@@ -36,6 +37,7 @@
  *
  * This verifies these failures when the APK targets R.
  */
+@Presubmit
 class PackageParsingDeferErrorTest {
 
     companion object {
diff --git a/services/tests/servicestests/src/com/android/server/pm/permission/LegacyPermissionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/permission/LegacyPermissionManagerServiceTest.java
index 3261dfa..3551af8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/permission/LegacyPermissionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/permission/LegacyPermissionManagerServiceTest.java
@@ -31,6 +31,7 @@
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Process;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -41,6 +42,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class LegacyPermissionManagerServiceTest {
     private static final int SYSTEM_UID = 1000;
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java
index 9d1c74b..a97ad8c 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeServiceConfigAccessor.java
@@ -151,12 +151,12 @@
     }
 
     @Override
-    public void setRecordProviderStateChanges(boolean enabled) {
+    public void setRecordStateChangesForTests(boolean enabled) {
         failUnimplemented();
     }
 
     @Override
-    public boolean getRecordProviderStateChanges() {
+    public boolean getRecordStateChangesForTests() {
         return failUnimplemented();
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TestState.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TestState.java
index 97b8360..97095c4 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TestState.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TestState.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * A test support class used for tracking a piece of state in test objects like fakes and mocks.
@@ -79,6 +80,11 @@
         assertEquals(expectedCount, getChangeCount());
     }
 
+    /** Asserts the value has been {@link #set} to the expected values in the order given. */
+    public void assertChanges(T... expected) {
+        assertEquals(Arrays.asList(expected), mValues);
+    }
+
     /**
      * Returns the latest value passed to {@link #set}. If {@link #set} hasn't been called then the
      * initial value is returned.
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderControllerTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderControllerTest.java
index 20c25a0..d54e1f1 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderControllerTest.java
@@ -21,6 +21,14 @@
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_INITIALIZING;
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_UNCERTAIN;
 import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STOPPED;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_CERTAIN;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_DESTROYED;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_FAILED;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_INITIALIZING;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_PROVIDERS_INITIALIZING;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_STOPPED;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_UNCERTAIN;
+import static com.android.server.timezonedetector.location.LocationTimeZoneProviderController.STATE_UNKNOWN;
 import static com.android.server.timezonedetector.location.TestSupport.USER1_CONFIG_GEO_DETECTION_DISABLED;
 import static com.android.server.timezonedetector.location.TestSupport.USER1_CONFIG_GEO_DETECTION_ENABLED;
 import static com.android.server.timezonedetector.location.TestSupport.USER2_CONFIG_GEO_DETECTION_ENABLED;
@@ -45,7 +53,9 @@
 import com.android.server.timezonedetector.ConfigurationInternal;
 import com.android.server.timezonedetector.GeolocationTimeZoneSuggestion;
 import com.android.server.timezonedetector.TestState;
+import com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderMetricsLogger;
 import com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.ProviderStateEnum;
+import com.android.server.timezonedetector.location.LocationTimeZoneProviderController.State;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -73,6 +83,7 @@
             TimeZoneProviderEvent.createPermanentFailureEvent(ARBITRARY_TIME_MILLIS, "Test");
 
     private TestThreadingDomain mTestThreadingDomain;
+    private TestMetricsLogger mTestMetricsLogger;
     private TestCallback mTestCallback;
     private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider;
     private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider;
@@ -82,11 +93,12 @@
         // For simplicity, the TestThreadingDomain uses the test's main thread. To execute posted
         // runnables, the test must call methods on mTestThreadingDomain otherwise those runnables
         // will never get a chance to execute.
-        LocationTimeZoneProvider.ProviderMetricsLogger stubbedProviderMetricsLogger = stateEnum -> {
-            // Stubbed.
-        };
         mTestThreadingDomain = new TestThreadingDomain();
+        mTestMetricsLogger = new TestMetricsLogger();
+
         mTestCallback = new TestCallback(mTestThreadingDomain);
+
+        ProviderMetricsLogger stubbedProviderMetricsLogger = stateEnum -> {};
         mTestPrimaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
                 stubbedProviderMetricsLogger, mTestThreadingDomain, "primary");
         mTestSecondaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
@@ -94,10 +106,18 @@
     }
 
     @Test
+    public void controllerStartsInUnknownState() {
+        LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
+        assertControllerState(controller, STATE_UNKNOWN);
+    }
+
+    @Test
     public void initializationFailure_primary() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
         Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout()
@@ -112,10 +132,13 @@
         mTestPrimaryLocationTimeZoneProvider.assertInitialized();
         mTestSecondaryLocationTimeZoneProvider.assertInitialized();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout);
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -123,8 +146,8 @@
     @Test
     public void initializationFailure_secondary() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
         Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout()
@@ -139,10 +162,13 @@
         mTestPrimaryLocationTimeZoneProvider.assertInitialized();
         mTestSecondaryLocationTimeZoneProvider.assertInitialized();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestPrimaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout);
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -150,8 +176,8 @@
     @Test
     public void initializationFailure_both() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
@@ -165,8 +191,11 @@
         mTestPrimaryLocationTimeZoneProvider.assertInitialized();
         mTestSecondaryLocationTimeZoneProvider.assertInitialized();
 
+        assertControllerState(controller, STATE_FAILED);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING, STATE_FAILED);
         mTestCallback.assertUncertainSuggestionMadeAndCommit();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -174,8 +203,8 @@
     @Test
     public void initialState_started() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
         Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout()
@@ -188,10 +217,13 @@
         mTestPrimaryLocationTimeZoneProvider.assertInitialized();
         mTestSecondaryLocationTimeZoneProvider.assertInitialized();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestPrimaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -199,8 +231,8 @@
     @Test
     public void initialState_disabled() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_DISABLED);
 
@@ -211,8 +243,10 @@
         mTestPrimaryLocationTimeZoneProvider.assertInitialized();
         mTestSecondaryLocationTimeZoneProvider.assertInitialized();
 
+        assertControllerState(controller, STATE_STOPPED);
         mTestPrimaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_PROVIDERS_INITIALIZING, STATE_STOPPED);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -220,8 +254,8 @@
     @Test
     public void enabled_uncertaintySuggestionSentIfNoEventReceived() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
@@ -231,18 +265,22 @@
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Simulate time passing with no provider event being received from the primary.
         mTestThreadingDomain.executeNext();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         // The primary should have reported uncertainty, which should trigger the controller to
         // start the uncertainty timeout and start the secondary.
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -250,12 +288,14 @@
         // secondary.
         mTestThreadingDomain.executeNext();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         // Now both initialization timeouts should have triggered. The uncertainty timeout should
         // still not be triggered.
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -263,10 +303,12 @@
         // suggestion.
         mTestThreadingDomain.executeNext();
 
+        assertControllerState(controller, STATE_UNCERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_UNCERTAIN);
         mTestCallback.assertUncertainSuggestionMadeAndCommit();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -274,17 +316,20 @@
     @Test
     public void enabled_eventReceivedBeforeInitializationTimeout() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -293,9 +338,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -304,27 +351,32 @@
     @Test
     public void enabled_eventReceivedFromPrimaryAfterInitializationTimeout() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Simulate time passing with no provider event being received from the primary.
         mTestThreadingDomain.executeNext();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -333,9 +385,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -344,27 +398,32 @@
     @Test
     public void enabled_eventReceivedFromSecondaryAfterInitializationTimeout() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Simulate time passing with no provider event being received from the primary.
         mTestThreadingDomain.executeNext();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -373,10 +432,12 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -385,17 +446,20 @@
     @Test
     public void enabled_repeatedPrimaryCertainty() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -404,9 +468,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -415,9 +481,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -425,9 +493,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -436,27 +506,32 @@
     @Test
     public void enabled_repeatedSecondaryCertainty() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Simulate time passing with no provider event being received from the primary.
         mTestThreadingDomain.executeNext();
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -465,10 +540,12 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -477,10 +554,12 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -488,10 +567,12 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -500,17 +581,20 @@
     @Test
     public void enabled_uncertaintyTriggersASuggestionAfterUncertaintyTimeout() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -519,9 +603,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -532,10 +618,12 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -545,10 +633,12 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -559,10 +649,12 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -570,10 +662,12 @@
         // suggestion should be made.
         mTestThreadingDomain.executeNext();
 
+        assertControllerState(controller, STATE_UNCERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_UNCERTAIN);
         mTestCallback.assertUncertainSuggestionMadeFromEventAndCommit(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -582,17 +676,20 @@
     @Test
     public void enabled_briefUncertaintyTriggersNoSuggestion() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -601,9 +698,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -613,10 +712,12 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -626,9 +727,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -637,33 +740,39 @@
     @Test
     public void configChanges_enableAndDisableWithNoPreviousSuggestion() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_DISABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_STOPPED);
         mTestPrimaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_PROVIDERS_INITIALIZING, STATE_STOPPED);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Now signal a config change so that geo detection is enabled.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Now signal a config change so that geo detection is disabled.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
 
+        assertControllerState(controller, STATE_STOPPED);
         mTestPrimaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_STOPPED);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -671,25 +780,29 @@
     @Test
     public void configChanges_enableAndDisableWithPreviousSuggestion() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_DISABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_STOPPED);
         mTestPrimaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_PROVIDERS_INITIALIZING, STATE_STOPPED);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Now signal a config change so that geo detection is enabled.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -697,9 +810,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -710,8 +825,10 @@
         // of the time zone.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
 
+        assertControllerState(controller, STATE_STOPPED);
         mTestPrimaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_UNCERTAIN, STATE_STOPPED);
         mTestCallback.assertUncertainSuggestionMadeAndCommit();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -719,17 +836,20 @@
     @Test
     public void configChanges_userSwitch_enabledToEnabled() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -739,9 +859,11 @@
 
         // Receiving a "success" provider event should cause a suggestion to be made synchronously,
         // and also clear the scheduled uncertainty suggestion.
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -750,7 +872,7 @@
         testEnvironment.simulateConfigChange(USER2_CONFIG_GEO_DETECTION_ENABLED);
 
         // Confirm that the previous suggestion was overridden.
-        mTestCallback.assertUncertainSuggestionMadeAndCommit();
+        assertControllerState(controller, STATE_INITIALIZING);
 
         // We expect the provider to end up in PROVIDER_STATE_STARTED_INITIALIZING, but it should
         // have been stopped when the user changed.
@@ -760,23 +882,29 @@
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfig(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER2_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_UNCERTAIN, STATE_STOPPED, STATE_INITIALIZING);
+        mTestCallback.assertUncertainSuggestionMadeAndCommit();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
 
     @Test
     public void primaryPermFailure_secondaryEventsReceived() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -785,9 +913,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -795,9 +925,11 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -806,9 +938,11 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -817,9 +951,11 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
     }
@@ -827,17 +963,20 @@
     @Test
     public void primaryPermFailure_disableAndEnable() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -846,26 +985,32 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Now signal a config change so that geo detection is disabled.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
 
+        assertControllerState(controller, STATE_STOPPED);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_STOPPED);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
         // Now signal a config change so that geo detection is enabled.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -873,17 +1018,20 @@
     @Test
     public void secondaryPermFailure_primaryEventsReceived() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -893,10 +1041,12 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -904,9 +1054,11 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -915,9 +1067,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -926,9 +1080,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
     }
@@ -936,17 +1092,20 @@
     @Test
     public void secondaryPermFailure_disableAndEnable() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -956,10 +1115,12 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
@@ -967,17 +1128,21 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertUncertaintyTimeoutSet(testEnvironment, controller);
 
         // Now signal a config change so that geo detection is disabled.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
 
+        assertControllerState(controller, STATE_STOPPED);
         mTestPrimaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_STOPPED);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -985,9 +1150,11 @@
         // started.
         testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -995,17 +1162,20 @@
     @Test
     public void bothPermFailure_disableAndEnable() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -1013,9 +1183,11 @@
         mTestPrimaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+        mTestMetricsLogger.assertStateChangesAndCommit();
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -1023,8 +1195,10 @@
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
                 USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
 
+        assertControllerState(controller, STATE_FAILED);
         mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
         mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_FAILED);
         mTestCallback.assertUncertainSuggestionMadeAndCommit();
         assertFalse(controller.isUncertaintyTimeoutSet());
     }
@@ -1033,8 +1207,8 @@
     public void stateRecording() {
         // The test provider enables state recording by default.
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, true /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
@@ -1043,12 +1217,15 @@
 
         {
             LocationTimeZoneManagerServiceState state = controller.getStateForTests();
+            assertEquals(STATE_INITIALIZING, state.getControllerState());
             assertNull(state.getLastSuggestion());
+            assertControllerRecordedStates(state,
+                    STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
             assertProviderStates(state.getPrimaryProviderStates(),
                     PROVIDER_STATE_STOPPED, PROVIDER_STATE_STARTED_INITIALIZING);
             assertProviderStates(state.getSecondaryProviderStates(), PROVIDER_STATE_STOPPED);
         }
-        controller.clearRecordedProviderStates();
+        controller.clearRecordedStates();
 
         // Simulate some provider behavior that will show up in the state recording.
 
@@ -1058,13 +1235,15 @@
 
         {
             LocationTimeZoneManagerServiceState state = controller.getStateForTests();
+            assertEquals(STATE_INITIALIZING, state.getControllerState());
             assertNull(state.getLastSuggestion());
+            assertControllerRecordedStates(state);
             assertProviderStates(
                     state.getPrimaryProviderStates(), PROVIDER_STATE_STARTED_UNCERTAIN);
             assertProviderStates(
                     state.getSecondaryProviderStates(), PROVIDER_STATE_STARTED_INITIALIZING);
         }
-        controller.clearRecordedProviderStates();
+        controller.clearRecordedStates();
 
         // Simulate a certain event from the secondary.
         mTestSecondaryLocationTimeZoneProvider.simulateTimeZoneProviderEvent(
@@ -1072,18 +1251,22 @@
 
         {
             LocationTimeZoneManagerServiceState state = controller.getStateForTests();
+            assertEquals(STATE_CERTAIN, state.getControllerState());
             assertEquals(USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getSuggestion().getTimeZoneIds(),
                     state.getLastSuggestion().getZoneIds());
+            assertControllerRecordedStates(state, STATE_CERTAIN);
             assertProviderStates(state.getPrimaryProviderStates());
             assertProviderStates(
                     state.getSecondaryProviderStates(), PROVIDER_STATE_STARTED_CERTAIN);
         }
 
-        controller.clearRecordedProviderStates();
+        controller.clearRecordedStates();
         {
             LocationTimeZoneManagerServiceState state = controller.getStateForTests();
+            assertEquals(STATE_CERTAIN, state.getControllerState());
             assertEquals(USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getSuggestion().getTimeZoneIds(),
                     state.getLastSuggestion().getZoneIds());
+            assertControllerRecordedStates(state);
             assertProviderStates(state.getPrimaryProviderStates());
             assertProviderStates(state.getSecondaryProviderStates());
         }
@@ -1101,17 +1284,20 @@
     @Test
     public void destroy() {
         LocationTimeZoneProviderController controller = new LocationTimeZoneProviderController(
-                mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider,
-                mTestSecondaryLocationTimeZoneProvider);
+                mTestThreadingDomain, mTestMetricsLogger, mTestPrimaryLocationTimeZoneProvider,
+                mTestSecondaryLocationTimeZoneProvider, false /* recordStateChanges */);
         TestEnvironment testEnvironment = new TestEnvironment(
                 mTestThreadingDomain, controller, USER1_CONFIG_GEO_DETECTION_ENABLED);
 
         // Initialize and check initial state.
         controller.initialize(testEnvironment, mTestCallback);
 
+        assertControllerState(controller, STATE_INITIALIZING);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_PROVIDERS_INITIALIZING, STATE_STOPPED, STATE_INITIALIZING);
         mTestCallback.assertNoSuggestionMade();
         assertFalse(controller.isUncertaintyTimeoutSet());
 
@@ -1121,9 +1307,11 @@
 
         // Receiving a "success" provider event should cause a suggestion to be made synchronously,
         // and also clear the scheduled uncertainty suggestion.
+        assertControllerState(controller, STATE_CERTAIN);
         mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
                 PROVIDER_STATE_STARTED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
         mTestSecondaryLocationTimeZoneProvider.assertIsStoppedAndCommit();
+        mTestMetricsLogger.assertStateChangesAndCommit(STATE_CERTAIN);
         mTestCallback.assertCertainSuggestionMadeFromEventAndCommit(
                 USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
         assertFalse(controller.isUncertaintyTimeoutSet());
@@ -1131,6 +1319,10 @@
         // Trigger destroy().
         controller.destroy();
 
+        assertControllerState(controller, STATE_DESTROYED);
+        mTestMetricsLogger.assertStateChangesAndCommit(
+                STATE_UNCERTAIN, STATE_STOPPED, STATE_DESTROYED);
+
         // Confirm that the previous suggestion was overridden.
         mTestCallback.assertUncertainSuggestionMadeAndCommit();
 
@@ -1158,6 +1350,17 @@
                         .build());
     }
 
+    private static void assertControllerState(LocationTimeZoneProviderController controller,
+            @State String expectedState) {
+        assertEquals(expectedState, controller.getStateForTests().getControllerState());
+    }
+
+    private static void assertControllerRecordedStates(
+            LocationTimeZoneManagerServiceState state,
+            @State String... expectedStates) {
+        assertEquals(Arrays.asList(expectedStates), state.getControllerStates());
+    }
+
     private static class TestEnvironment extends LocationTimeZoneProviderController.Environment {
 
         // These timeouts are set deliberately so that:
@@ -1229,6 +1432,22 @@
         }
     }
 
+    private static class TestMetricsLogger
+            implements LocationTimeZoneProviderController.MetricsLogger {
+
+        private final TestState<@State String> mLatestStateEnum = new TestState<>();
+
+        @Override
+        public void onStateChange(@State String stateEnum) {
+            mLatestStateEnum.set(stateEnum);
+        }
+
+        public void assertStateChangesAndCommit(@State String... expectedStateEnums) {
+            mLatestStateEnum.assertChanges(expectedStateEnums);
+            mLatestStateEnum.commitLatest();
+        }
+    }
+
     private static class TestCallback extends LocationTimeZoneProviderController.Callback {
 
         private TestState<GeolocationTimeZoneSuggestion> mLatestSuggestion = new TestState<>();
diff --git a/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java b/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java
index 3716507..7eb6c97 100644
--- a/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/uri/UriGrantsMockContext.java
@@ -16,7 +16,7 @@
 
 package com.android.server.uri;
 
-import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -121,47 +121,47 @@
         LocalServices.addService(PackageManagerInternal.class, mPmInternal);
 
         for (int userId : new int[] { USER_PRIMARY, USER_SECONDARY }) {
-            when(mPmInternal.getPackageUid(eq(PKG_SOCIAL), anyInt(), eq(userId)))
+            when(mPmInternal.getPackageUid(eq(PKG_SOCIAL), anyLong(), eq(userId)))
                     .thenReturn(UserHandle.getUid(userId, UID_SOCIAL));
-            when(mPmInternal.getPackageUid(eq(PKG_CAMERA), anyInt(), eq(userId)))
+            when(mPmInternal.getPackageUid(eq(PKG_CAMERA), anyLong(), eq(userId)))
                     .thenReturn(UserHandle.getUid(userId, UID_CAMERA));
-            when(mPmInternal.getPackageUid(eq(PKG_PRIVATE), anyInt(), eq(userId)))
+            when(mPmInternal.getPackageUid(eq(PKG_PRIVATE), anyLong(), eq(userId)))
                     .thenReturn(UserHandle.getUid(userId, UID_PRIVATE));
-            when(mPmInternal.getPackageUid(eq(PKG_PUBLIC), anyInt(), eq(userId)))
+            when(mPmInternal.getPackageUid(eq(PKG_PUBLIC), anyLong(), eq(userId)))
                     .thenReturn(UserHandle.getUid(userId, UID_PUBLIC));
-            when(mPmInternal.getPackageUid(eq(PKG_FORCE), anyInt(), eq(userId)))
+            when(mPmInternal.getPackageUid(eq(PKG_FORCE), anyLong(), eq(userId)))
                     .thenReturn(UserHandle.getUid(userId, UID_FORCE));
-            when(mPmInternal.getPackageUid(eq(PKG_COMPLEX), anyInt(), eq(userId)))
+            when(mPmInternal.getPackageUid(eq(PKG_COMPLEX), anyLong(), eq(userId)))
                     .thenReturn(UserHandle.getUid(userId, UID_COMPLEX));
 
-            when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyLong(), eq(userId),
                     eq(Process.SYSTEM_UID)))
                     .thenReturn(buildCameraProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyLong(), eq(userId),
                     eq(UserHandle.getUid(userId, UID_CAMERA))))
                     .thenReturn(buildCameraProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyLong(), eq(userId),
                     eq(Process.SYSTEM_UID)))
                     .thenReturn(buildPrivateProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyLong(), eq(userId),
                     eq(UserHandle.getUid(userId, UID_PRIVATE))))
                     .thenReturn(buildPrivateProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyLong(), eq(userId),
                     eq(Process.SYSTEM_UID)))
                     .thenReturn(buildPublicProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyLong(), eq(userId),
                     eq(UserHandle.getUid(userId, UID_PUBLIC))))
                     .thenReturn(buildPublicProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyLong(), eq(userId),
                     eq(Process.SYSTEM_UID)))
                     .thenReturn(buildForceProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyLong(), eq(userId),
                     eq(UserHandle.getUid(userId, UID_FORCE))))
                     .thenReturn(buildForceProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyLong(), eq(userId),
                     eq(Process.SYSTEM_UID)))
                     .thenReturn(buildComplexProvider(userId));
-            when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyInt(), eq(userId),
+            when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyLong(), eq(userId),
                     eq(UserHandle.getUid(userId, UID_COMPLEX))))
                     .thenReturn(buildComplexProvider(userId));
         }
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 9e46e1f..949ee01 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -63,6 +63,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -530,8 +531,8 @@
                     eq(UserHandle.getAppId(ai.uid)), eq(userIdForTest), anyLong()))
                     .thenReturn(idle[i]);
         }
-        when(mInjector.mPackageManagerInternal.getInstalledApplications(anyInt(), eq(userIdForTest),
-                anyInt())).thenReturn(installedApps);
+        when(mInjector.mPackageManagerInternal.getInstalledApplications(anyLong(),
+                eq(userIdForTest), anyInt())).thenReturn(installedApps);
         final int[] returnedIdleUids = controllerUnderTest.getIdleUidsForUser(userIdForTest);
 
         assertEquals(expectedIdleUids.length, returnedIdleUids.length);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index 4eb9c06..c0f7596 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -126,15 +126,23 @@
             new VibrationAttributes.Builder().setUsage(
                     VibrationAttributes.USAGE_RINGTONE).build();
 
-    @Rule public MockitoRule rule = MockitoJUnit.rule();
-    @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+    @Rule
+    public MockitoRule rule = MockitoJUnit.rule();
+    @Rule
+    public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
 
-    @Mock private VibratorManagerService.NativeWrapper mNativeWrapperMock;
-    @Mock private PackageManagerInternal mPackageManagerInternalMock;
-    @Mock private PowerManagerInternal mPowerManagerInternalMock;
-    @Mock private PowerSaveState mPowerSaveStateMock;
-    @Mock private AppOpsManager mAppOpsManagerMock;
-    @Mock private IInputManager mIInputManagerMock;
+    @Mock
+    private VibratorManagerService.NativeWrapper mNativeWrapperMock;
+    @Mock
+    private PackageManagerInternal mPackageManagerInternalMock;
+    @Mock
+    private PowerManagerInternal mPowerManagerInternalMock;
+    @Mock
+    private PowerSaveState mPowerSaveStateMock;
+    @Mock
+    private AppOpsManager mAppOpsManagerMock;
+    @Mock
+    private IInputManager mIInputManagerMock;
 
     private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
 
@@ -397,6 +405,7 @@
     @Test
     public void registerVibratorStateListener_multipleVibratorsAreTriggered() throws Exception {
         mockVibrators(0, 1, 2);
+        mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
         VibratorManagerService service = createSystemReadyService();
         IVibratorStateListener[] listeners = new IVibratorStateListener[3];
         for (int i = 0; i < 3; i++) {
@@ -601,8 +610,8 @@
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
         AudioAttributes audioAttributes = new AudioAttributes.Builder()
                 .setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY).build();
-        VibrationAttributes vibrationAttributes = new VibrationAttributes.Builder(
-                audioAttributes, effect).build();
+        VibrationAttributes vibrationAttributes =
+                new VibrationAttributes.Builder(audioAttributes).build();
 
         vibrate(service, effect, vibrationAttributes);
 
@@ -621,7 +630,7 @@
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
                 new VibrationAttributes.Builder().setUsage(
                         VibrationAttributes.USAGE_COMMUNICATION_REQUEST).build());
-        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK),
+        vibrate(service, VibrationEffect.createOneShot(2000, 200),
                 new VibrationAttributes.Builder().setUsage(
                         VibrationAttributes.USAGE_UNKNOWN).build());
 
@@ -642,6 +651,60 @@
     }
 
     @Test
+    public void vibrate_withAttributesUnknownUsage_usesEffectToIdentifyTouchUsage() {
+        VibratorManagerService service = createSystemReadyService();
+
+        VibrationAttributes unknownAttributes = VibrationAttributes.createForUsage(
+                VibrationAttributes.USAGE_UNKNOWN);
+        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), unknownAttributes);
+        vibrate(service, VibrationEffect.createOneShot(200, 200), unknownAttributes);
+        vibrate(service, VibrationEffect.createWaveform(
+                new long[] { 100, 200, 300 }, new int[] {1, 2, 3}, -1), unknownAttributes);
+        vibrate(service,
+                VibrationEffect.startComposition()
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL)
+                        .compose(),
+                unknownAttributes);
+
+        verify(mAppOpsManagerMock, times(4))
+                .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE),
+                        eq(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION), anyInt(), anyString());
+        verify(mAppOpsManagerMock, never())
+                .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE),
+                        eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString());
+    }
+
+    @Test
+    public void vibrate_withAttributesUnknownUsage_ignoresEffectIfNotHapticFeedbackCandidate() {
+        VibratorManagerService service = createSystemReadyService();
+
+        VibrationAttributes unknownAttributes = VibrationAttributes.createForUsage(
+                VibrationAttributes.USAGE_UNKNOWN);
+        vibrate(service, VibrationEffect.get(VibrationEffect.RINGTONES[0]), unknownAttributes);
+        vibrate(service, VibrationEffect.createOneShot(2000, 200), unknownAttributes);
+        vibrate(service, VibrationEffect.createWaveform(
+                new long[] { 100, 200, 300 }, new int[] {1, 2, 3}, 0), unknownAttributes);
+        vibrate(service,
+                VibrationEffect.startComposition()
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK)
+                        .compose(),
+                unknownAttributes);
+
+        verify(mAppOpsManagerMock, never())
+                .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE),
+                        eq(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION), anyInt(), anyString());
+        verify(mAppOpsManagerMock, times(4))
+                .checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE),
+                        eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString());
+    }
+
+    @Test
     public void vibrate_withOngoingRepeatingVibration_ignoresEffect() throws Exception {
         mockVibrators(1);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index cdb7230..2f054b00 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -809,7 +810,7 @@
                     service.isComponentEnabledForCurrentProfiles(
                             unapprovedAdditionalComponent));
             verify(mIpm, never()).getServiceInfo(
-                    eq(unapprovedAdditionalComponent), anyInt(), anyInt());
+                    eq(unapprovedAdditionalComponent), anyLong(), anyInt());
         }
     }
 
@@ -953,7 +954,7 @@
                     service.isComponentEnabledForCurrentProfiles(
                             unapprovedAdditionalComponent));
             verify(mIpm, never()).getServiceInfo(
-                    eq(unapprovedAdditionalComponent), anyInt(), anyInt());
+                    eq(unapprovedAdditionalComponent), anyLong(), anyInt());
         }
     }
 
@@ -1702,14 +1703,14 @@
                             assertTrue(service.isComponentEnabledForCurrentProfiles(
                                     componentName));
                             verify(mIpm, times(1)).getServiceInfo(
-                                    eq(componentName), anyInt(), anyInt());
+                                    eq(componentName), anyLong(), anyInt());
                         }
                     } else {
                         ComponentName componentName =
                                 ComponentName.unflattenFromString(packageOrComponent);
                         assertTrue(service.isComponentEnabledForCurrentProfiles(componentName));
                         verify(mIpm, times(1)).getServiceInfo(
-                                eq(componentName), anyInt(), anyInt());
+                                eq(componentName), anyLong(), anyInt());
                     }
                 }
             }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 622669a..837850f 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -397,7 +397,7 @@
         // MockPackageManager - default returns ApplicationInfo with matching calling UID
         mContext.setMockPackageManager(mPackageManagerClient);
 
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), anyInt()))
                 .thenAnswer((Answer<ApplicationInfo>) invocation -> {
                     Object[] args = invocation.getArguments();
                     return getApplicationInfo((String) args[0], mUid);
@@ -5043,7 +5043,7 @@
     public void testIsCallerInstantApp_primaryUser() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(0))).thenReturn(info);
         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
 
         assertTrue(mService.isCallerInstantApp(45770, 0));
@@ -5056,8 +5056,8 @@
     public void testIsCallerInstantApp_secondaryUser() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(10))).thenReturn(info);
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(null);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(10))).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(0))).thenReturn(null);
         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
 
         assertTrue(mService.isCallerInstantApp(68638450, 10));
@@ -5067,7 +5067,7 @@
     public void testIsCallerInstantApp_userAllNotification() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(USER_SYSTEM)))
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(USER_SYSTEM)))
                 .thenReturn(info);
         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
 
@@ -5081,8 +5081,8 @@
     public void testResolveNotificationUid_sameApp_nonSystemUser() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.uid = Binder.getCallingUid();
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(10))).thenReturn(info);
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(null);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(10))).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(0))).thenReturn(null);
 
         int actualUid = mService.resolveNotificationUid("caller", "caller", info.uid, 10);
 
@@ -5093,7 +5093,7 @@
     public void testResolveNotificationUid_sameApp() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.uid = Binder.getCallingUid();
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(0))).thenReturn(info);
 
         int actualUid = mService.resolveNotificationUid("caller", "caller", info.uid, 0);
 
@@ -5104,7 +5104,7 @@
     public void testResolveNotificationUid_sameAppDiffPackage() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.uid = Binder.getCallingUid();
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(0))).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), eq(0))).thenReturn(info);
 
         int actualUid = mService.resolveNotificationUid("caller", "callerAlso", info.uid, 0);
 
@@ -5115,7 +5115,7 @@
     public void testResolveNotificationUid_sameAppWrongUid() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.uid = 1356347;
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(info);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), anyInt())).thenReturn(info);
 
         try {
             mService.resolveNotificationUid("caller", "caller", 9, 0);
@@ -5154,7 +5154,7 @@
                 PackageManager.NameNotFoundException.class);
         ApplicationInfo ai = new ApplicationInfo();
         ai.uid = -1;
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(ai);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), anyInt())).thenReturn(ai);
 
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         try {
@@ -5174,7 +5174,7 @@
                 PackageManager.NameNotFoundException.class);
         ApplicationInfo ai = new ApplicationInfo();
         ai.uid = -1;
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())).thenReturn(ai);
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), anyInt())).thenReturn(ai);
 
         // unlike the post case, ignore instead of throwing
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
index 29ef339..2e5cf3c 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
@@ -44,6 +44,7 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doNothing;
@@ -307,7 +308,7 @@
         // MockPackageManager - default returns ApplicationInfo with matching calling UID
         mContext.setMockPackageManager(mPackageManagerClient);
 
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
+        when(mPackageManager.getApplicationInfo(anyString(), anyLong(), anyInt()))
                 .thenAnswer((Answer<ApplicationInfo>) invocation -> {
                     Object[] args = invocation.getArguments();
                     return getApplicationInfo((String) args[0], mUid);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index 4cdae88..5800400 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -28,6 +28,7 @@
 
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
@@ -42,7 +43,6 @@
 import android.permission.IPermissionManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Pair;
-import android.util.Slog;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -169,7 +169,8 @@
 
         ParceledListSlice<PackageInfo> infos = new ParceledListSlice<>(
                 ImmutableList.of(notThis, none, first, second));
-        when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS), anyInt())).thenReturn(infos);
+        when(mPackageManager.getInstalledPackages(eq((long) GET_PERMISSIONS), anyInt()))
+                .thenReturn(infos);
 
         Set<Pair<Integer, String>> actual = mPermissionHelper.getAppsRequestingPermission(0);
 
@@ -181,7 +182,7 @@
         int userId = 1;
         ParceledListSlice<PackageInfo> infos = ParceledListSlice.emptyList();
         when(mPackageManager.getPackagesHoldingPermissions(
-                eq(new String[] {Manifest.permission.POST_NOTIFICATIONS}), anyInt(), eq(userId)))
+                eq(new String[] {Manifest.permission.POST_NOTIFICATIONS}), anyLong(), eq(userId)))
                 .thenReturn(infos);
         assertThat(mPermissionHelper.getAppsGrantedPermission(userId)).isNotNull();
     }
@@ -206,7 +207,7 @@
         ParceledListSlice<PackageInfo> infos = new ParceledListSlice<>(
                 ImmutableList.of(first, second));
         when(mPackageManager.getPackagesHoldingPermissions(
-                eq(new String[] {Manifest.permission.POST_NOTIFICATIONS}), anyInt(), eq(userId)))
+                eq(new String[] {Manifest.permission.POST_NOTIFICATIONS}), anyLong(), eq(userId)))
                 .thenReturn(infos);
 
         Set<Pair<Integer, String>> expected =
@@ -305,11 +306,11 @@
         ParceledListSlice<PackageInfo> infos = new ParceledListSlice<>(
                 ImmutableList.of(first, second));
         when(mPackageManager.getPackagesHoldingPermissions(
-                eq(new String[] {Manifest.permission.POST_NOTIFICATIONS}), anyInt(), eq(userId)))
+                eq(new String[] {Manifest.permission.POST_NOTIFICATIONS}), anyLong(), eq(userId)))
                 .thenReturn(infos);
         ParceledListSlice<PackageInfo> requesting = new ParceledListSlice<>(
                 ImmutableList.of(first, second, third));
-        when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS), anyInt()))
+        when(mPackageManager.getInstalledPackages(eq((long) GET_PERMISSIONS), anyInt()))
                 .thenReturn(requesting);
 
         Map<Pair<Integer, String>, Boolean> expected = ImmutableMap.of(new Pair(1, "first"), true,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 0cab911..e2f0658f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -63,6 +63,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.notNull;
@@ -352,7 +353,7 @@
         doReturn(null).when(mMockPackageManager).getDefaultHomeActivity(anyInt());
         doReturn(mMockPackageManager).when(mAtm).getPackageManagerInternalLocked();
         doReturn(false).when(mMockPackageManager).isInstantAppInstallerComponent(any());
-        doReturn(null).when(mMockPackageManager).resolveIntent(any(), any(), anyInt(), anyInt(),
+        doReturn(null).when(mMockPackageManager).resolveIntent(any(), any(), anyLong(), anyLong(),
                 anyInt(), anyBoolean(), anyInt());
         doReturn(new ComponentName("", "")).when(mMockPackageManager).getSystemUiServiceComponent();
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index cac7978..c18798f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -114,11 +114,16 @@
         flickerRule.checkFlakyAssertions()
     }
 
-    /** {@inheritDoc} */
+    /**
+     * Windows maybe recreated when rotated. Checks that the focus does not change or if it does,
+     * focus returns to [testApp]
+     */
     @FlakyTest(bugId = 190185577)
     @Test
-    override fun focusDoesNotChange() {
-        super.focusDoesNotChange()
+    fun focusChanges() {
+        testSpec.assertEventLog {
+            this.focusChanges(testApp.`package`)
+        }
     }
 
     /**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index ce2347d..d1bdeed 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -129,17 +129,6 @@
     open fun entireScreenCovered() = testSpec.entireScreenCovered()
 
     /**
-     * Checks that the focus doesn't change during animation
-     */
-    @Presubmit
-    @Test
-    open fun focusDoesNotChange() {
-        testSpec.assertEventLog {
-            this.focusDoesNotChange()
-        }
-    }
-
-    /**
      * Checks that [testApp] layer covers the entire screen at the start of the transition
      */
     @Presubmit
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 3ca60e3..e44bee6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -146,15 +146,6 @@
         }
     }
 
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun focusDoesNotChange() {
-        // This test doesn't work in shell transitions because of b/206101151
-        assumeFalse(isShellTransitionsEnabled)
-        super.focusDoesNotChange()
-    }
-
     /**
      * Checks that [testApp] layer covers the entire screen during the whole transition
      */
@@ -196,6 +187,19 @@
         }
     }
 
+    /**
+     * Checks that the focus doesn't change during animation
+     */
+    @Presubmit
+    @Test
+    fun focusDoesNotChange() {
+        // This test doesn't work in shell transitions because of b/206101151
+        assumeFalse(isShellTransitionsEnabled)
+        testSpec.assertEventLog {
+            this.focusDoesNotChange()
+        }
+    }
+
     /** {@inheritDoc} */
     @FlakyTest
     @Test
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java
index 7ea2a62d..d4bc2a6 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java
@@ -42,7 +42,7 @@
         swView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         frame.addView(swView);
         final RectsView hwBothView = new RectsView(this, 850, Color.GREEN);
-        // Don't actually need to render to a hw layer, but it's a good sanity-check that
+        // Don't actually need to render to a hw layer, but it's a good check that
         // we're rendering to/from layers correctly
         hwBothView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         frame.addView(hwBothView);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java
index 7173a85..584ab59 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/Lines2Activity.java
@@ -42,7 +42,7 @@
         swView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         frame.addView(swView);
         final LinesView hwBothView = new LinesView(this, 850, Color.GREEN);
-        // Don't actually need to render to a hw layer, but it's a good sanity-check that
+        // Don't actually need to render to a hw layer, but it's a good check that
         // we're rendering to/from layers correctly
         hwBothView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         frame.addView(hwBothView);