Merge changes I0e699465,If2bc354f

* changes:
  Remove mSupportsLongpress from KeyButtonView
  Remove keyRepeat from KeyButtonView
diff --git a/api/current.txt b/api/current.txt
index 60d99dc..3e7d626 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -25699,14 +25699,14 @@
   public static class MediaPlayer2.DrmEventCallback {
     ctor public MediaPlayer2.DrmEventCallback();
     method public void onDrmConfig(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm);
-    method public android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(android.media.MediaPlayer2, android.media.DataSourceDesc, android.media.MediaPlayer2.DrmInfo);
-    method public byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest);
+    method @Nullable public android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo);
+    method @NonNull public byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest);
     method public void onDrmPrepared(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, @Nullable byte[]);
   }
 
   public static final class MediaPlayer2.DrmInfo {
-    method public java.util.Map<java.util.UUID,byte[]> getPssh();
-    method public java.util.List<java.util.UUID> getSupportedSchemes();
+    method @NonNull public java.util.Map<java.util.UUID,byte[]> getPssh();
+    method @NonNull public java.util.List<java.util.UUID> getSupportedSchemes();
   }
 
   public static final class MediaPlayer2.DrmPreparationInfo {
@@ -25714,13 +25714,13 @@
 
   public static final class MediaPlayer2.DrmPreparationInfo.Builder {
     ctor public MediaPlayer2.DrmPreparationInfo.Builder();
-    method public android.media.MediaPlayer2.DrmPreparationInfo build();
-    method public android.media.MediaPlayer2.DrmPreparationInfo.Builder setInitData(@Nullable byte[]);
-    method public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeySetId(@Nullable byte[]);
-    method public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeyType(int);
-    method public android.media.MediaPlayer2.DrmPreparationInfo.Builder setMimeType(@Nullable String);
-    method public android.media.MediaPlayer2.DrmPreparationInfo.Builder setOptionalParameters(@Nullable java.util.Map<java.lang.String,java.lang.String>);
-    method public android.media.MediaPlayer2.DrmPreparationInfo.Builder setUuid(@NonNull java.util.UUID);
+    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo build();
+    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setInitData(@Nullable byte[]);
+    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeySetId(@Nullable byte[]);
+    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeyType(int);
+    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setMimeType(@Nullable String);
+    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setOptionalParameters(@Nullable java.util.Map<java.lang.String,java.lang.String>);
+    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setUuid(@NonNull java.util.UUID);
   }
 
   public static class MediaPlayer2.EventCallback {
@@ -25751,7 +25751,7 @@
   }
 
   public static final class MediaPlayer2.NoDrmSchemeException extends android.media.MediaDrmException {
-    ctor public MediaPlayer2.NoDrmSchemeException(String);
+    ctor public MediaPlayer2.NoDrmSchemeException(@Nullable String);
   }
 
   public static class MediaPlayer2.TrackInfo {
@@ -53033,7 +53033,7 @@
     method public int describeContents();
     method @NonNull public static android.view.contentcapture.ContentCaptureContext forLocusId(@NonNull String);
     method @Nullable public android.os.Bundle getExtras();
-    method @NonNull public android.content.LocusId getLocusId();
+    method @Nullable public android.content.LocusId getLocusId();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureContext> CREATOR;
   }
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 6432c24..b82e517 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -935,12 +935,16 @@
     }
 
     /**
-     * Returns the value associated with the given key, or null if
-     * no mapping of the desired type exists for the given key or a null
+     * Returns the value associated with the given key, or {@code null} if
+     * no mapping of the desired type exists for the given key or a {@code null}
      * value is explicitly associated with the key.
      *
-     * @param key a String, or null
-     * @return a Parcelable value, or null
+     * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
+     * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
+     * Otherwise, this method might throw an exception or return {@code null}.
+     *
+     * @param key a String, or {@code null}
+     * @return a Parcelable value, or {@code null}
      */
     @Nullable
     public <T extends Parcelable> T getParcelable(@Nullable String key) {
@@ -958,12 +962,16 @@
     }
 
     /**
-     * Returns the value associated with the given key, or null if
+     * Returns the value associated with the given key, or {@code null} if
      * no mapping of the desired type exists for the given key or a null
      * value is explicitly associated with the key.
      *
-     * @param key a String, or null
-     * @return a Parcelable[] value, or null
+     * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
+     * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
+     * Otherwise, this method might throw an exception or return {@code null}.
+     *
+     * @param key a String, or {@code null}
+     * @return a Parcelable[] value, or {@code null}
      */
     @Nullable
     public Parcelable[] getParcelableArray(@Nullable String key) {
@@ -981,12 +989,16 @@
     }
 
     /**
-     * Returns the value associated with the given key, or null if
-     * no mapping of the desired type exists for the given key or a null
+     * Returns the value associated with the given key, or {@code null} if
+     * no mapping of the desired type exists for the given key or a {@code null}
      * value is explicitly associated with the key.
      *
-     * @param key a String, or null
-     * @return an ArrayList<T> value, or null
+     * <p><b>Note: </b> if the expected value is not a class provided by the Android platform,
+     * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first.
+     * Otherwise, this method might throw an exception or return {@code null}.
+     *
+     * @param key a String, or {@code null}
+     * @return an ArrayList<T> value, or {@code null}
      */
     @Nullable
     public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index dd38373..b8174e6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -12598,8 +12598,9 @@
 
         /**
          * Battery level [1-100] at which low power mode automatically turns on.
-         * Pre-Q If 0, it will not automatically turn on. Q and newer it will only automatically
-         * turn on if the {@link #AUTOMATIC_POWER_SAVER_MODE} setting is also set to
+         * If 0, it will not automatically turn on. For Q and newer, it will only automatically
+         * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVER_MODE}
+         * setting is also set to
          * {@link android.os.PowerManager.AutoPowerSaverMode#POWER_SAVER_MODE_PERCENTAGE}.
          *
          * @see #AUTOMATIC_POWER_SAVER_MODE
diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java
index 019ebff..5a27e94 100644
--- a/core/java/android/view/contentcapture/ContentCaptureContext.java
+++ b/core/java/android/view/contentcapture/ContentCaptureContext.java
@@ -161,7 +161,7 @@
     /**
      * Gets the context id.
      */
-    @NonNull
+    @Nullable
     public LocusId getLocusId() {
         return mId;
     }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 050b2ec..01f1798 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -167,9 +167,9 @@
 
     /**
      * Broadcast intent action when the set of enabled location providers changes. To check the
-     * status of a provider, use {@link #isProviderEnabled(String)}. Depending on API level, may
+     * status of a provider, use {@link #isProviderEnabled(String)}. From Android Q and above, will
      * include a string intent extra, {@link #EXTRA_PROVIDER_NAME}, with the name of the provider
-     * whose state has changed. See {@link #EXTRA_PROVIDER_NAME} for the supported API level.
+     * whose state has changed.
      *
      * @see #EXTRA_PROVIDER_NAME
      */
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 5cd3621..fbe184b 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -3463,7 +3463,7 @@
              * @param uuid of selected crypto scheme
              * @return this
              */
-            public Builder setUuid(@NonNull UUID uuid) {
+            public @NonNull Builder setUuid(@NonNull UUID uuid) {
                 this.mUUID = uuid;
                 return this;
             }
@@ -3480,7 +3480,7 @@
              * @param keySetId identifier of a persisted offline key
              * @return this
              */
-            public Builder setKeySetId(@Nullable byte[] keySetId) {
+            public @NonNull Builder setKeySetId(@Nullable byte[] keySetId) {
                 this.mKeySetId = keySetId;
                 return this;
             }
@@ -3494,7 +3494,7 @@
              * @param initData container-specific DRM initialization data
              * @return this
              */
-            public Builder setInitData(@Nullable byte[] initData) {
+            public @NonNull Builder setInitData(@Nullable byte[] initData) {
                 this.mInitData = initData;
                 return this;
             }
@@ -3505,7 +3505,7 @@
              * @param mimeType mime type to the content
              * @return this
              */
-            public Builder setMimeType(@Nullable String mimeType) {
+            public @NonNull Builder setMimeType(@Nullable String mimeType) {
                 this.mMimeType = mimeType;
                 return this;
             }
@@ -3519,7 +3519,7 @@
              * @param keyType type of the key request
              * @return this
              */
-            public Builder setKeyType(@MediaPlayer2.MediaDrmKeyType int keyType) {
+            public @NonNull Builder setKeyType(@MediaPlayer2.MediaDrmKeyType int keyType) {
                 this.mKeyType = keyType;
                 return this;
             }
@@ -3531,7 +3531,8 @@
              * @param optionalParameters optional parameters to be included in a key request
              * @return this
              */
-            public Builder setOptionalParameters(@Nullable Map<String, String> optionalParameters) {
+            public @NonNull Builder setOptionalParameters(
+                    @Nullable Map<String, String> optionalParameters) {
                 this.mOptionalParameters = optionalParameters;
                 return this;
             }
@@ -3540,7 +3541,7 @@
              * @return an immutable {@link MediaPlayer2.DrmPreparationInfo} representing the
              *         settings of this builder
              */
-            public MediaPlayer2.DrmPreparationInfo build() {
+            public @NonNull MediaPlayer2.DrmPreparationInfo build() {
                 return new MediaPlayer2.DrmPreparationInfo(mUUID, mKeySetId, mInitData, mMimeType,
                         mKeyType, mOptionalParameters);
             }
@@ -3597,7 +3598,8 @@
          * @return a {@link DrmPreparationInfo} object to initialize DRM playback, or null to skip
          *         DRM initialization
          */
-        public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd, DrmInfo drmInfo) {
+        public @Nullable DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp,
+                @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo) {
             return null;
         }
 
@@ -3630,11 +3632,13 @@
          * @param request a {@link MediaDrm.KeyRequest} prepared using the
          *        {@link DrmPreparationInfo} returned from
          *        {@link #onDrmInfo(MediaPlayer2, DataSourceDesc, DrmInfo)}
-         * @return the response to {@code request} (from license server)
+         * @return the response to {@code request} (from license server); returning {@code null} or
+         *         throwing an {@link RuntimeException} from this callback would trigger an
+         *         {@link EventCallback#onError}.
          */
-        public byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @NonNull MediaDrm.KeyRequest request) {
-            return null;
+        public @NonNull byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp,
+                @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request) {
+            return new byte[0];
         }
 
         /**
@@ -4144,7 +4148,7 @@
         /**
          * Returns the PSSH info of the data source for each supported DRM scheme.
          */
-        public Map<UUID, byte[]> getPssh() {
+        public @NonNull Map<UUID, byte[]> getPssh() {
             return mMapPssh;
         }
 
@@ -4153,7 +4157,7 @@
          * It effectively identifies the subset of the source's DRM schemes which
          * are supported by the device too.
          */
-        public List<UUID> getSupportedSchemes() {
+        public @NonNull List<UUID> getSupportedSchemes() {
             return Arrays.asList(mSupportedSchemes);
         }
 
@@ -4276,7 +4280,7 @@
      * Extends MediaDrm.MediaDrmException
      */
     public static final class NoDrmSchemeException extends MediaDrmException {
-        public NoDrmSchemeException(String detailMessage) {
+        public NoDrmSchemeException(@Nullable String detailMessage) {
             super(detailMessage);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index d06feed..2db7306 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -61,7 +61,9 @@
 
     @Override
     public void onDestroy() {
-        mPluginManager.removePluginListener(this);
+        if (mPluginManager != null) {
+            mPluginManager.removePluginListener(this);
+        }
         super.onDestroy();
         mDozeMachine = null;
     }
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a400cc3..3d918fc 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -83,6 +83,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
 import android.util.SparseLongArray;
 import android.util.StatsLog;
 import android.util.TimeUtils;
@@ -195,6 +196,7 @@
     private final Injector mInjector;
     int mBroadcastRefCount = 0;
     PowerManager.WakeLock mWakeLock;
+    SparseIntArray mAlarmsPerUid = new SparseIntArray();
     ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>();
     ArrayList<InFlight> mInFlight = new ArrayList<>();
     private final ArrayList<AlarmManagerInternal.InFlightListener> mInFlightListeners =
@@ -393,6 +395,8 @@
         @VisibleForTesting
         static final String KEY_LISTENER_TIMEOUT = "listener_timeout";
         @VisibleForTesting
+        static final String KEY_MAX_ALARMS_PER_UID = "max_alarms_per_uid";
+        @VisibleForTesting
         static final String KEY_APP_STANDBY_QUOTAS_ENABLED = "app_standby_quotas_enabled";
         private static final String KEY_APP_STANDBY_WINDOW = "app_standby_window";
         @VisibleForTesting
@@ -420,6 +424,7 @@
         private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 9*60*1000;
         private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000;
         private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000;
+        private static final int DEFAULT_MAX_ALARMS_PER_UID = 500;
         private static final boolean DEFAULT_APP_STANDBY_QUOTAS_ENABLED = true;
         private static final long DEFAULT_APP_STANDBY_WINDOW = 60 * 60 * 1000;  // 1 hr
         /**
@@ -461,6 +466,8 @@
 
         // Direct alarm listener callback timeout
         public long LISTENER_TIMEOUT = DEFAULT_LISTENER_TIMEOUT;
+        public int MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID;
+
         public boolean APP_STANDBY_QUOTAS_ENABLED = DEFAULT_APP_STANDBY_QUOTAS_ENABLED;
 
         public long APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW;
@@ -549,6 +556,15 @@
                     APP_STANDBY_QUOTAS[i] = mParser.getInt(KEYS_APP_STANDBY_QUOTAS[i],
                             Math.min(APP_STANDBY_QUOTAS[i - 1], DEFAULT_APP_STANDBY_QUOTAS[i]));
                 }
+
+                MAX_ALARMS_PER_UID = mParser.getInt(KEY_MAX_ALARMS_PER_UID,
+                        DEFAULT_MAX_ALARMS_PER_UID);
+                if (MAX_ALARMS_PER_UID < DEFAULT_MAX_ALARMS_PER_UID) {
+                    Slog.w(TAG, "Cannot set " + KEY_MAX_ALARMS_PER_UID + " lower than "
+                            + DEFAULT_MAX_ALARMS_PER_UID);
+                    MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID;
+                }
+
                 updateAllowWhileIdleWhitelistDurationLocked();
             }
         }
@@ -590,6 +606,9 @@
             TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw);
             pw.println();
 
+            pw.print(KEY_MAX_ALARMS_PER_UID); pw.print("=");
+            pw.println(MAX_ALARMS_PER_UID);
+
             for (int i = 0; i < KEYS_APP_STANDBY_DELAY.length; i++) {
                 pw.print(KEYS_APP_STANDBY_DELAY[i]); pw.print("=");
                 TimeUtils.formatDuration(APP_STANDBY_MIN_DELAYS[i], pw);
@@ -671,12 +690,6 @@
 
         final ArrayList<Alarm> alarms = new ArrayList<Alarm>();
 
-        Batch() {
-            start = 0;
-            end = Long.MAX_VALUE;
-            flags = 0;
-        }
-
         Batch(Alarm seed) {
             start = seed.whenElapsed;
             end = clampPositive(seed.maxWhenElapsed);
@@ -728,11 +741,16 @@
             return newStart;
         }
 
+        /**
+         * Remove an alarm from this batch.
+         * <p> <b> Should be used only while re-ordering the alarm within the service </b> as it
+         * does not update {@link #mAlarmsPerUid}
+         */
         boolean remove(Alarm alarm) {
-            return remove(a -> (a == alarm));
+            return remove(a -> (a == alarm), true);
         }
 
-        boolean remove(Predicate<Alarm> predicate) {
+        boolean remove(Predicate<Alarm> predicate, boolean reOrdering) {
             boolean didRemove = false;
             long newStart = 0;  // recalculate endpoints as we go
             long newEnd = Long.MAX_VALUE;
@@ -741,6 +759,9 @@
                 Alarm alarm = alarms.get(i);
                 if (predicate.test(alarm)) {
                     alarms.remove(i);
+                    if (!reOrdering) {
+                        decrementAlarmCount(alarm.uid);
+                    }
                     didRemove = true;
                     if (alarm.alarmClock != null) {
                         mNextAlarmClockMayChange = true;
@@ -1734,6 +1755,15 @@
                         + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed
                         + " interval=" + interval + " flags=0x" + Integer.toHexString(flags));
             }
+            if (mAlarmsPerUid.get(callingUid, 0) >= mConstants.MAX_ALARMS_PER_UID) {
+                final String errorMsg =
+                        "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID
+                                + " reached for uid: " + UserHandle.formatUid(callingUid)
+                                + ", callingPackage: " + callingPackage;
+                // STOPSHIP (b/128866264): Just to catch breakages. Remove before final release.
+                Slog.wtf(TAG, errorMsg);
+                throw new UnsupportedOperationException(errorMsg);
+            }
             setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
                     interval, operation, directReceiver, listenerTag, flags, true, workSource,
                     alarmClock, callingUid, callingPackage);
@@ -1756,6 +1786,7 @@
         } catch (RemoteException e) {
         }
         removeLocked(operation, directReceiver);
+        incrementAlarmCount(a.uid);
         setImplLocked(a, false, doValidate);
     }
 
@@ -2197,7 +2228,6 @@
                             ? sdf.format(new Date(nowRTC - (nowELAPSED - time)))
                             : "-");
                 } while (i != mNextTickHistory);
-                pw.println();
             }
 
             SystemServiceManager ssm = LocalServices.getService(SystemServiceManager.class);
@@ -2305,6 +2335,18 @@
             if (!blocked) {
                 pw.println("    none");
             }
+            pw.println();
+            pw.print("  Pending alarms per uid: [");
+            for (int i = 0; i < mAlarmsPerUid.size(); i++) {
+                if (i > 0) {
+                    pw.print(", ");
+                }
+                UserHandle.formatUid(pw, mAlarmsPerUid.keyAt(i));
+                pw.print(":");
+                pw.print(mAlarmsPerUid.valueAt(i));
+            }
+            pw.println("]");
+            pw.println();
 
             mAppWakeupHistory.dump(pw, "  ", nowELAPSED);
 
@@ -3046,7 +3088,7 @@
         final Predicate<Alarm> whichAlarms = (Alarm a) -> a.matches(operation, directReceiver);
         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
             Batch b = mAlarmBatches.get(i);
-            didRemove |= b.remove(whichAlarms);
+            didRemove |= b.remove(whichAlarms, false);
             if (b.size() == 0) {
                 mAlarmBatches.remove(i);
             }
@@ -3098,7 +3140,7 @@
         final Predicate<Alarm> whichAlarms = (Alarm a) -> a.uid == uid;
         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
             Batch b = mAlarmBatches.get(i);
-            didRemove |= b.remove(whichAlarms);
+            didRemove |= b.remove(whichAlarms, false);
             if (b.size() == 0) {
                 mAlarmBatches.remove(i);
             }
@@ -3145,7 +3187,7 @@
         final boolean oldHasTick = haveBatchesTimeTickAlarm(mAlarmBatches);
         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
             Batch b = mAlarmBatches.get(i);
-            didRemove |= b.remove(whichAlarms);
+            didRemove |= b.remove(whichAlarms, false);
             if (b.size() == 0) {
                 mAlarmBatches.remove(i);
             }
@@ -3183,6 +3225,7 @@
         }
     }
 
+    // Only called for ephemeral apps
     void removeForStoppedLocked(final int uid) {
         if (uid == Process.SYSTEM_UID) {
             Slog.wtf(TAG, "removeForStoppedLocked: Shouldn't for UID=" + uid);
@@ -3200,7 +3243,7 @@
         };
         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
             Batch b = mAlarmBatches.get(i);
-            didRemove |= b.remove(whichAlarms);
+            didRemove |= b.remove(whichAlarms, false);
             if (b.size() == 0) {
                 mAlarmBatches.remove(i);
             }
@@ -3237,7 +3280,7 @@
                 (Alarm a) -> UserHandle.getUserId(a.creatorUid) == userHandle;
         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
             Batch b = mAlarmBatches.get(i);
-            didRemove |= b.remove(whichAlarms);
+            didRemove |= b.remove(whichAlarms, false);
             if (b.size() == 0) {
                 mAlarmBatches.remove(i);
             }
@@ -3407,8 +3450,7 @@
         return mConstants.ALLOW_WHILE_IDLE_LONG_TIME;
     }
 
-    boolean triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED,
-            final long nowRTC) {
+    boolean triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED) {
         boolean hasWakeup = false;
         // batches are temporally sorted, so we need only pull from the
         // start of the list until we either empty it or hit a batch
@@ -3984,7 +4026,7 @@
                         }
 
                         mLastTrigger = nowELAPSED;
-                        boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
+                        boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED);
                         if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
                             // if there are no wakeup alarms and the screen is off, we can
                             // delay what we have so far until the future.
@@ -4108,9 +4150,8 @@
                 case ALARM_EVENT: {
                     ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
                     synchronized (mLock) {
-                        final long nowRTC = mInjector.getCurrentTimeMillis();
                         final long nowELAPSED = mInjector.getElapsedRealtime();
-                        triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
+                        triggerAlarmsLocked(triggerList, nowELAPSED);
                         updateNextAlarmClockLocked();
                     }
 
@@ -4719,7 +4760,7 @@
                 mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage,
                         UserHandle.getUserId(alarm.creatorUid), nowELAPSED);
             }
-
+            decrementAlarmCount(alarm.uid);
             final BroadcastStats bs = inflight.mBroadcastStats;
             bs.count++;
             if (bs.nesting == 0) {
@@ -4747,6 +4788,27 @@
         }
     }
 
+    private void incrementAlarmCount(int uid) {
+        final int uidIndex = mAlarmsPerUid.indexOfKey(uid);
+        if (uidIndex >= 0) {
+            mAlarmsPerUid.setValueAt(uidIndex, mAlarmsPerUid.valueAt(uidIndex) + 1);
+        } else {
+            mAlarmsPerUid.put(uid, 1);
+        }
+    }
+
+    private void decrementAlarmCount(int uid) {
+        final int uidIndex = mAlarmsPerUid.indexOfKey(uid);
+        if (uidIndex >= 0) {
+            final int newCount = mAlarmsPerUid.valueAt(uidIndex) - 1;
+            if (newCount > 0) {
+                mAlarmsPerUid.setValueAt(uidIndex, newCount);
+            } else {
+                mAlarmsPerUid.removeAt(uidIndex);
+            }
+        }
+    }
+
     private class ShellCmd extends ShellCommand {
 
         IAlarmManager getBinderService() {
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 3ab3c34..833faa6 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -115,7 +115,8 @@
  *
  * Test: atest com.android.server.DeviceIdleControllerTest
  *
- * Current idling state machine (as of Android 9 Pie). This can be visualized using Graphviz:
+ * Current idling state machine (as of Android Q). This can be visualized using Graphviz:
+   <pre>
 
    digraph {
      subgraph deep {
@@ -259,6 +260,7 @@
        ]
      }
    }
+   </pre>
  */
 public class DeviceIdleController extends SystemService
         implements AnyMotionDetector.DeviceIdleCallback {
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 7fab2b96..6ef5b54 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -102,6 +102,7 @@
 import com.android.server.location.GeofenceProxy;
 import com.android.server.location.GnssBatchingProvider;
 import com.android.server.location.GnssLocationProvider;
+import com.android.server.location.GnssMeasurementCorrectionsProvider;
 import com.android.server.location.GnssMeasurementsProvider;
 import com.android.server.location.GnssNavigationMessageProvider;
 import com.android.server.location.GnssStatusListenerHelper;
@@ -195,6 +196,7 @@
     private PassiveProvider mPassiveProvider;  // track passive provider for special cases
     private LocationBlacklist mBlacklist;
     private GnssMeasurementsProvider mGnssMeasurementsProvider;
+    private GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
     private GnssNavigationMessageProvider mGnssNavigationMessageProvider;
     @GuardedBy("mLock")
     private String mLocationControllerExtraPackage;
@@ -309,9 +311,13 @@
                 AppOpsManager.WATCH_FOREGROUND_CHANGES,
                 new AppOpsManager.OnOpChangedInternalListener() {
                     public void onOpChanged(int op, String packageName) {
-                        synchronized (mLock) {
-                            onAppOpChangedLocked();
-                        }
+                        // onOpChanged invoked on ui thread, move to our thread to reduce risk of
+                        // blocking ui thread
+                        mHandler.post(() -> {
+                            synchronized (mLock) {
+                                onAppOpChangedLocked();
+                            }
+                        });
                     }
                 });
         mPackageManager.addOnPermissionsChangeListener(
@@ -757,6 +763,8 @@
             mGnssStatusProvider = gnssProvider.getGnssStatusProvider();
             mNetInitiatedListener = gnssProvider.getNetInitiatedListener();
             mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider();
+            mGnssMeasurementCorrectionsProvider =
+                    gnssProvider.getGnssMeasurementCorrectionsProvider();
             mGnssNavigationMessageProvider = gnssProvider.getGnssNavigationMessageProvider();
             mGpsGeofenceProxy = gnssProvider.getGpsGeofenceProxy();
         }
@@ -2921,22 +2929,28 @@
         mContext.enforceCallingPermission(
                 android.Manifest.permission.LOCATION_HARDWARE,
                 "Location Hardware permission not granted to inject GNSS measurement corrections.");
-        if (!hasGnssPermissions(packageName) || mGnssMeasurementsProvider == null) {
+        if (!hasGnssPermissions(packageName)) {
             Slog.e(TAG, "Can not inject GNSS corrections due to no permission.");
-        } else {
-            mGnssMeasurementsProvider.injectGnssMeasurementCorrections(measurementCorrections);
+            return;
         }
+        if (mGnssMeasurementCorrectionsProvider == null) {
+            Slog.e(TAG, "Can not inject GNSS corrections. GNSS measurement corrections provider "
+                    + "not available.");
+            return;
+        }
+        mGnssMeasurementCorrectionsProvider.injectGnssMeasurementCorrections(
+                measurementCorrections);
     }
 
     @Override
     public int getGnssCapabilities(String packageName) {
         mContext.enforceCallingPermission(
                 android.Manifest.permission.LOCATION_HARDWARE,
-                "Location Hardware permission not granted to obrain GNSS chipset capabilities.");
-        if (!hasGnssPermissions(packageName) || mGnssMeasurementsProvider == null) {
+                "Location Hardware permission not granted to obtain GNSS chipset capabilities.");
+        if (!hasGnssPermissions(packageName) || mGnssMeasurementCorrectionsProvider == null) {
             return -1;
         }
-        return mGnssMeasurementsProvider.getGnssCapabilities();
+        return mGnssMeasurementCorrectionsProvider.getCapabilities();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java
index 09df7e20..d8d6528 100644
--- a/services/core/java/com/android/server/am/AssistDataRequester.java
+++ b/services/core/java/com/android/server/am/AssistDataRequester.java
@@ -24,6 +24,7 @@
 
 import android.app.ActivityTaskManager;
 import android.app.AppOpsManager;
+import android.app.IActivityTaskManager;
 import android.app.IAssistDataReceiver;
 import android.content.Context;
 import android.graphics.Bitmap;
@@ -33,6 +34,7 @@
 import android.view.IWindowManager;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 
 import java.io.PrintWriter;
@@ -50,6 +52,8 @@
     public static final String KEY_RECEIVER_EXTRA_INDEX = "index";
 
     private IWindowManager mWindowManager;
+    @VisibleForTesting
+    public IActivityTaskManager mActivityTaskManager;
     private Context mContext;
     private AppOpsManager mAppOpsManager;
 
@@ -128,6 +132,7 @@
         mCallbacks = callbacks;
         mCallbacksLock = callbacksLock;
         mWindowManager = windowManager;
+        mActivityTaskManager = ActivityTaskManager.getService();
         mContext = context;
         mAppOpsManager = appOpsManager;
         mRequestStructureAppOps = requestStructureAppOps;
@@ -195,8 +200,7 @@
         // Ensure that the current activity supports assist data
         boolean isAssistDataAllowed = false;
         try {
-            isAssistDataAllowed =
-                    ActivityTaskManager.getService().isAssistDataAllowedOnCurrentActivity();
+            isAssistDataAllowed = mActivityTaskManager.isAssistDataAllowedOnCurrentActivity();
         } catch (RemoteException e) {
             // Should never happen
         }
@@ -222,9 +226,9 @@
                         receiverExtras.putInt(KEY_RECEIVER_EXTRA_INDEX, i);
                         receiverExtras.putInt(KEY_RECEIVER_EXTRA_COUNT, numActivities);
                         boolean result = requestAutofillData
-                                ? ActivityTaskManager.getService().requestAutofillData(this,
+                                ? mActivityTaskManager.requestAutofillData(this,
                                         receiverExtras, topActivity, 0 /* flags */)
-                                : ActivityTaskManager.getService().requestAssistContextExtras(
+                                : mActivityTaskManager.requestAssistContextExtras(
                                         ASSIST_CONTEXT_FULL, this, receiverExtras, topActivity,
                                         /* focused= */ i == 0, /* newSessionId= */ i == 0);
                         if (result) {
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index c173d66..8249999 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -166,9 +166,15 @@
     private static final int GPS_CAPABILITY_MSA = 0x0000004;
     private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
     private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
-    private static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
+
+    // The following three capability flags are removed in IGnssCallback.hal@2.0 and their values
+    // are marked reserved and not reused in 2.0 to avoid confusion with prior versions.
+    public static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
     public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
-    private static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
+    public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
+
+    private static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100;
+    private static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200;
 
     // The AGPS SUPL mode
     private static final int AGPS_SUPL_MODE_MSA = 0x02;
@@ -333,7 +339,7 @@
     private boolean mStarted;
 
     // capabilities of the GPS engine
-    private int mEngineCapabilities;
+    private volatile int mEngineCapabilities;
 
     // true if XTRA is supported
     private boolean mSupportsXtra;
@@ -372,6 +378,7 @@
     private final LocationExtras mLocationExtras = new LocationExtras();
     private final GnssStatusListenerHelper mGnssStatusListenerHelper;
     private final GnssMeasurementsProvider mGnssMeasurementsProvider;
+    private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
     private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
     private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
     private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
@@ -437,6 +444,10 @@
         return mGnssMeasurementsProvider;
     }
 
+    public GnssMeasurementCorrectionsProvider getGnssMeasurementCorrectionsProvider() {
+        return mGnssMeasurementCorrectionsProvider;
+    }
+
     public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
         return mGnssNavigationMessageProvider;
     }
@@ -627,6 +638,8 @@
             }
         };
 
+        mGnssMeasurementCorrectionsProvider = new GnssMeasurementCorrectionsProvider(mHandler);
+
         mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
             @Override
             protected boolean isGpsEnabled() {
@@ -1258,6 +1271,10 @@
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
     }
 
+    public int getGnssCapabilities() {
+        return mEngineCapabilities;
+    }
+
     private boolean hasCapability(int capability) {
         return ((mEngineCapabilities & capability) != 0);
     }
@@ -1467,22 +1484,27 @@
     }
 
     @NativeEntryPoint
-    private void setEngineCapabilities(final int capabilities) {
+    private void setEngineCapabilities(final int capabilities, boolean hasSubHalCapabilityFlags) {
         // send to handler thread for fast native return, and in-order handling
-        mHandler.post(
-                () -> {
-                    mEngineCapabilities = capabilities;
+        mHandler.post(() -> {
+            mEngineCapabilities = capabilities;
 
-                    if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
-                        mNtpTimeHelper.enablePeriodicTimeInjection();
-                        requestUtcTime();
-                    }
+            if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
+                mNtpTimeHelper.enablePeriodicTimeInjection();
+                requestUtcTime();
+            }
 
-                    mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities);
-                    mGnssNavigationMessageProvider.onCapabilitiesUpdated(
-                            hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
-                    restartRequests();
-                });
+            mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities, hasSubHalCapabilityFlags);
+            mGnssNavigationMessageProvider.onCapabilitiesUpdated(capabilities,
+                    hasSubHalCapabilityFlags);
+            restartRequests();
+        });
+    }
+
+    @NativeEntryPoint
+    private void setMeasurementCorrectionsCapabilities(final int capabilities) {
+        mHandler.post(() -> mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(
+                capabilities));
     }
 
     private void restartRequests() {
@@ -2122,7 +2144,23 @@
         if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
         if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
         if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
+        if (hasCapability(GPS_CAPABILITY_LOW_POWER_MODE)) s.append("LOW_POWER_MODE ");
+        if (hasCapability(GPS_CAPABILITY_SATELLITE_BLACKLIST)) s.append("SATELLITE_BLACKLIST ");
         s.append(")\n");
+        if (mGnssGeofenceProvider.isHardwareGeofenceSupported()) {
+            s.append("  hasSubHal=GEOFENCING\n");
+        }
+        if (mGnssMeasurementsProvider.isAvailableInPlatform()) {
+            s.append("  hasSubHal=MEASUREMENTS\n");
+        }
+        if (mGnssNavigationMessageProvider.isAvailableInPlatform()) {
+            s.append("  hasSubHal=NAV_MESSAGES\n");
+        }
+        if (mGnssMeasurementCorrectionsProvider.isAvailableInPlatform()) {
+            s.append("  hasSubHal=MEASUREMENT_CORRECTIONS [");
+            s.append(mGnssMeasurementCorrectionsProvider.toStringCapabilities());
+            s.append("]\n");
+        }
         s.append(mGnssMetrics.dumpGnssMetricsAsText());
         s.append("  native internal state: ").append(native_get_internal_state());
         s.append("\n");
diff --git a/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java
new file mode 100644
index 0000000..2162787
--- /dev/null
+++ b/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2019 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.server.location;
+
+import android.location.GnssMeasurementCorrections;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Manages GNSS measurement corrections.
+ *
+ * <p>Implements the framework side of the GNSS HAL interfaces {@code IMeasurementCorrections.hal}
+ * and {@code IMeasurementCorrectionsCallback.hal).
+ *
+ * @hide
+ */
+public class GnssMeasurementCorrectionsProvider {
+    private static final String TAG = "GnssMeasurementCorrectionsProvider";
+
+    // These must match with the Capabilities enum in IMeasurementCorrectionsCallback.hal.
+    private static final int CAPABILITY_LOS_SATS = 0x0000001;
+    private static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002;
+    private static final int CAPABILITY_REFLECTING_PLANE = 0x0000004;
+
+    private static final int INVALID_CAPABILITIES = 1 << 31;
+
+    private final Handler mHandler;
+    private final GnssMeasurementCorrectionsProviderNative mNative;
+    private volatile int mCapabilities = INVALID_CAPABILITIES;
+
+    GnssMeasurementCorrectionsProvider(Handler handler) {
+        this(handler, new GnssMeasurementCorrectionsProviderNative());
+    }
+
+    @VisibleForTesting
+    GnssMeasurementCorrectionsProvider(Handler handler,
+            GnssMeasurementCorrectionsProviderNative aNative) {
+        mHandler = handler;
+        mNative = aNative;
+    }
+
+    /**
+     * Returns {@code true} if the GNSS HAL implementation supports measurement corrections.
+     */
+    public boolean isAvailableInPlatform() {
+        return mNative.isMeasurementCorrectionsSupported();
+    }
+
+    /**
+     * Injects GNSS measurement corrections into the GNSS chipset.
+     *
+     * @param measurementCorrections a {@link GnssMeasurementCorrections} object with the GNSS
+     *     measurement corrections to be injected into the GNSS chipset.
+     */
+    public void injectGnssMeasurementCorrections(
+            GnssMeasurementCorrections measurementCorrections) {
+        if (!isCapabilitiesReceived()) {
+            Log.w(TAG, "Failed to inject GNSS measurement corrections. Capabilities "
+                    + "not received yet.");
+            return;
+        }
+        mHandler.post(() -> {
+            if (!mNative.injectGnssMeasurementCorrections(measurementCorrections)) {
+                Log.e(TAG, "Failure in injecting GNSS corrections.");
+            }
+        });
+    }
+
+    /** Handle measurement corrections capabilities update from the GNSS HAL implementation. */
+    void onCapabilitiesUpdated(int capabilities) {
+        if (hasCapability(capabilities, CAPABILITY_LOS_SATS) || hasCapability(capabilities,
+                CAPABILITY_EXCESS_PATH_LENGTH)) {
+            mCapabilities = capabilities;
+        } else {
+            Log.e(TAG, "Failed to set capabilities. Received capabilities 0x"
+                    + Integer.toHexString(capabilities) + " does not contain the mandatory "
+                    + "LOS_SATS or the EXCESS_PATH_LENGTH capability.");
+        }
+    }
+
+    /**
+     * Returns the measurement corrections specific capabilities of the GNSS HAL implementation.
+     */
+    public int getCapabilities() {
+        return mCapabilities;
+    }
+
+    /**
+     * Returns the string representation of the GNSS measurement capabilities.
+     */
+    String toStringCapabilities() {
+        final int capabilities = getCapabilities();
+        StringBuilder s = new StringBuilder();
+        s.append("mCapabilities=0x").append(Integer.toHexString(capabilities));
+        s.append(" ( ");
+        if (hasCapability(capabilities, CAPABILITY_LOS_SATS)) {
+            s.append("LOS_SATS ");
+        }
+        if (hasCapability(capabilities, CAPABILITY_EXCESS_PATH_LENGTH)) {
+            s.append("EXCESS_PATH_LENGTH ");
+        }
+        if (hasCapability(capabilities, CAPABILITY_REFLECTING_PLANE)) {
+            s.append("REFLECTING_PLANE ");
+        }
+        s.append(")");
+        return s.toString();
+    }
+
+    private boolean isCapabilitiesReceived() {
+        return mCapabilities != INVALID_CAPABILITIES;
+    }
+
+    private static  boolean hasCapability(int halCapabilities, int capability) {
+        return (halCapabilities & capability) != 0;
+    }
+
+    @VisibleForTesting
+    static class GnssMeasurementCorrectionsProviderNative {
+        public boolean isMeasurementCorrectionsSupported() {
+            return native_is_measurement_corrections_supported();
+        }
+
+        public boolean injectGnssMeasurementCorrections(
+                GnssMeasurementCorrections measurementCorrections) {
+            return native_inject_gnss_measurement_corrections(measurementCorrections);
+        }
+    }
+
+    private static native boolean native_is_measurement_corrections_supported();
+
+    private static native boolean native_inject_gnss_measurement_corrections(
+            GnssMeasurementCorrections measurementCorrections);
+}
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index 1fc7192..844735a 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -11,13 +11,12 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.server.location;
 
 import android.content.Context;
-import android.location.GnssMeasurementCorrections;
 import android.location.GnssMeasurementsEvent;
 import android.location.IGnssMeasurementsListener;
 import android.os.Handler;
@@ -42,7 +41,6 @@
 
     private boolean mIsCollectionStarted;
     private boolean mEnableFullTracking;
-    private int mGnssEngineCapabilities;
 
     protected GnssMeasurementsProvider(Context context, Handler handler) {
         this(context, handler, new GnssMeasurementProviderNative());
@@ -87,21 +85,6 @@
         }
     }
 
-    /**
-     * Injects GNSS measurement corrections into the GNSS chipset.
-     *
-     * @param measurementCorrections a {@link GnssMeasurementCorrections} object with the GNSS
-     *     measurement corrections to be injected into the GNSS chipset.
-     */
-    public void injectGnssMeasurementCorrections(
-            GnssMeasurementCorrections measurementCorrections) {
-        mHandler.post(() -> {
-            if (!mNative.injectGnssMeasurementCorrections(measurementCorrections)) {
-                Log.e(TAG, "Failure in injecting GNSS corrections.");
-            }
-        });
-    }
-
     @Override
     protected void unregisterFromService() {
         boolean stopped = mNative.stopMeasurementCollection();
@@ -121,20 +104,20 @@
         });
     }
 
-    /** Updates the framework about the capabilities of the GNSS chipset */
-    public void onCapabilitiesUpdated(int capabilities) {
-        mGnssEngineCapabilities = capabilities;
-        boolean isGnssMeasurementsSupported =
-                (capabilities & GnssLocationProvider.GPS_CAPABILITY_MEASUREMENTS) != 0;
+    /** Handle GNSS capabilities update from the GNSS HAL implementation. */
+    public void onCapabilitiesUpdated(int capabilities, boolean hasSubHalCapabilityFlags) {
+        // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum
+        // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate
+        // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the
+        // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs
+        // which explicitly set the sub-HAL capability bits must continue to work.
+        final boolean isGnssMeasurementsSupported = hasSubHalCapabilityFlags
+                ? (capabilities & GnssLocationProvider.GPS_CAPABILITY_MEASUREMENTS) != 0
+                : mNative.isMeasurementSupported();
         setSupported(isGnssMeasurementsSupported);
         updateResult();
     }
 
-    /** Obtains the GNSS engine capabilities. */
-    public int getGnssCapabilities() {
-        return mGnssEngineCapabilities;
-    }
-
     public void onGpsEnabledChanged() {
         tryUpdateRegistrationWithService();
         updateResult();
@@ -195,11 +178,6 @@
         public boolean stopMeasurementCollection() {
             return native_stop_measurement_collection();
         }
-
-        public boolean injectGnssMeasurementCorrections(
-                GnssMeasurementCorrections measurementCorrections) {
-            return native_inject_gnss_measurement_corrections(measurementCorrections);
-        }
     }
 
     private static native boolean native_is_measurement_supported();
@@ -207,7 +185,4 @@
     private static native boolean native_start_measurement_collection(boolean enableFullTracking);
 
     private static native boolean native_stop_measurement_collection();
-
-    private static native boolean native_inject_gnss_measurement_corrections(
-            GnssMeasurementCorrections measurementCorrections);
 }
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 80a3f9b..7e8b599 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -11,7 +11,7 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.server.location;
@@ -51,7 +51,6 @@
         mNative = aNative;
     }
 
-    // TODO(b/37460011): Use this with death recovery logic.
     void resumeIfStarted() {
         if (DEBUG) {
             Log.d(TAG, "resumeIfStarted");
@@ -92,7 +91,16 @@
         );
     }
 
-    public void onCapabilitiesUpdated(boolean isGnssNavigationMessageSupported) {
+    /** Handle GNSS capabilities update from the GNSS HAL implementation */
+    public void onCapabilitiesUpdated(int capabilities, boolean hasSubHalCapabilityFlags) {
+        // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum
+        // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate
+        // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the
+        // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs
+        // which explicitly set the sub-HAL capability bits must continue to work.
+        final boolean isGnssNavigationMessageSupported = hasSubHalCapabilityFlags
+                ? (capabilities & GnssLocationProvider.GPS_CAPABILITY_NAV_MESSAGES) != 0
+                : mNative.isNavigationMessageSupported();
         setSupported(isGnssNavigationMessageSupported);
         updateResult();
     }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index aced1a2..459de1a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2693,6 +2693,7 @@
                 // seinfo     - seinfo label for the app (assigned at install time)
                 // gids       - supplementary gids this app launches with
                 // profileableFromShellFlag  - 0 or 1 if the package is profileable from shell.
+                // longVersionCode - integer version of the package.
                 //
                 // NOTE: We prefer not to expose all ApplicationInfo flags for now.
                 //
@@ -2720,6 +2721,8 @@
                 }
                 sb.append(" ");
                 sb.append(ai.isProfileableByShell() ? "1" : "0");
+                sb.append(" ");
+                sb.append(String.valueOf(ai.longVersionCode));
                 sb.append("\n");
                 writer.append(sb);
             }
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 050a079..00b815a 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -109,6 +109,7 @@
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
+        "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
         "android.hardware.input.classifier@1.0",
         "android.hardware.ir@1.0",
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index caba3af..a4955f0 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -71,6 +71,7 @@
 static jmethodID method_reportNavigationMessages;
 static jmethodID method_reportLocationBatch;
 static jmethodID method_reportGnssServiceDied;
+static jmethodID method_setMeasurementCorrectionsCapabilities;
 static jmethodID method_correctionsGetLatitudeDegrees;
 static jmethodID method_correctionsGetLongitudeDegrees;
 static jmethodID method_correctionsGetAltitudeMeters;
@@ -158,10 +159,9 @@
 using IAGnssCallback_V1_0 = android::hardware::gnss::V1_0::IAGnssCallback;
 using IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
 
-using IMeasurementCorrections =
-    android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
-using GnssSingleSatCorrectionFlags =
-    android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
+using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
+using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
+using android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
 
 using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
 using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback;
@@ -201,7 +201,6 @@
 sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr;
 sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
 sp<IMeasurementCorrections> gnssCorrectionsIface = nullptr;
-
 sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;
 
 #define WAKE_LOCK_NAME  "GPS"
@@ -572,7 +571,9 @@
     template <class T>
     Return<void> gnssLocationCbImpl(const T& location);
 
-    // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
+    Return<void> gnssSetCapabilitesCbImpl(uint32_t capabilities, bool hasSubHalCapabilityFlags);
+
+    // TODO: Reconsider allocation cost vs threadsafety on these statics
     static const char* sNmeaString;
     static size_t sNmeaStringLength;
 };
@@ -694,16 +695,29 @@
 }
 
 Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
-    ALOGD("%s: %du\n", __func__, capabilities);
-
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
+    return GnssCallback::gnssSetCapabilitesCbImpl(capabilities,
+        /* hasSubHalCapabilityFlags = */ true);
 }
 
 Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
-    return GnssCallback::gnssSetCapabilitesCb(capabilities);
+    return GnssCallback::gnssSetCapabilitesCbImpl(capabilities,
+        /* hasSubHalCapabilityFlags = */ false);
+}
+
+Return <void> GnssCallback::gnssSetCapabilitesCbImpl(uint32_t capabilities,
+        bool hasSubHalCapabilityFlags) {
+    // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum
+    // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate
+    // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the
+    // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs
+    // which explicitly set the sub-HAL capability bits must continue to work.
+    ALOGD("%s: capabilities=%du, hasSubHalCapabilityFlags=%d\n", __func__, capabilities,
+        hasSubHalCapabilityFlags);
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities,
+            boolToJbool(hasSubHalCapabilityFlags));
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
 }
 
 Return<void> GnssCallback::gnssAcquireWakelockCb() {
@@ -1153,6 +1167,22 @@
 }
 
 /*
+ * MeasurementCorrectionsCallback implements callback methods of interface
+ * IMeasurementCorrectionsCallback.hal.
+ */
+struct MeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback {
+    Return<void> setCapabilitiesCb(uint32_t capabilities) override;
+};
+
+Return<void> MeasurementCorrectionsCallback::setCapabilitiesCb(uint32_t capabilities) {
+    ALOGD("%s: %du\n", __func__, capabilities);
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_setMeasurementCorrectionsCapabilities, capabilities);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+/*
  * GnssNiCallback implements callback methods required by the IGnssNi interface.
  */
 struct GnssNiCallback : public IGnssNiCallback {
@@ -1434,7 +1464,7 @@
     method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
     method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
     method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
-    method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
+    method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(IZ)V");
     method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
     method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
             "(Ljava/lang/String;)V");
@@ -1474,6 +1504,9 @@
             "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
     method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
 
+    method_setMeasurementCorrectionsCapabilities = env->GetMethodID(clazz,
+            "setMeasurementCorrectionsCapabilities", "(I)V");
+
     jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections");
     method_correctionsGetLatitudeDegrees = env->GetMethodID(
             measCorrClass,"getLatitudeDegrees", "()D");
@@ -1591,7 +1624,7 @@
     }
 
     if (gnssHal_V2_0 != nullptr) {
-        // TODO(b/119638366): getExtensionGnssMeasurement_1_1 from gnssHal_V2_0
+        // TODO: getExtensionGnssMeasurement_1_1 from gnssHal_V2_0
         auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
         if (!gnssMeasurement.isOk()) {
             ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
@@ -1795,6 +1828,12 @@
         gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
     }
 
+    if (gnssCorrectionsIface != nullptr) {
+        sp<IMeasurementCorrectionsCallback> gnssCorrectionsIfaceCbIface =
+                new MeasurementCorrectionsCallback();
+        gnssCorrectionsIface->setCallback(gnssCorrectionsIfaceCbIface);
+    }
+
     return JNI_TRUE;
 }
 
@@ -2154,7 +2193,7 @@
                                                                        jobject /* obj */) {
     jstring result = nullptr;
     /*
-     * TODO(b/33089503) : Create a jobject to represent GnssDebug.
+     * TODO: Create a jobject to represent GnssDebug.
      */
 
     std::stringstream internalState;
@@ -2380,13 +2419,25 @@
     return boolToJbool(result.isOk());
 }
 
-static jboolean android_location_GnssMeasurementsProvider_inject_gnss_measurement_corrections(
+static jboolean
+    android_location_GnssMeasurementCorrectionsProvider_is_measurement_corrections_supported(
+    JNIEnv* env, jclass clazz) {
+    if (gnssCorrectionsIface != nullptr) {
+        return JNI_TRUE;
+    }
+
+    return JNI_FALSE;
+}
+
+static jboolean
+    android_location_GnssMeasurementCorrectionsProvider_inject_gnss_measurement_corrections(
         JNIEnv* env,
         jobject obj /* clazz*/,
         jobject correctionsObj) {
 
     if (gnssCorrectionsIface == nullptr) {
-        ALOGW("Trying to inject GNSS corrections on a chipset that does not support them.");
+        ALOGW("Trying to inject GNSS measurement corrections on a chipset that does not"
+            " support them.");
         return JNI_FALSE;
     }
 
@@ -2882,18 +2933,25 @@
 static const JNINativeMethod sMeasurementMethods[] = {
     /* name, signature, funcPtr */
     {"native_is_measurement_supported", "()Z",
-     reinterpret_cast<void*>(
-         android_location_GnssMeasurementsProvider_is_measurement_supported)},
+            reinterpret_cast<void*>(
+            android_location_GnssMeasurementsProvider_is_measurement_supported)},
     {"native_start_measurement_collection", "(Z)Z",
-     reinterpret_cast<void*>(
-         android_location_GnssMeasurementsProvider_start_measurement_collection)},
+            reinterpret_cast<void*>(
+            android_location_GnssMeasurementsProvider_start_measurement_collection)},
     {"native_stop_measurement_collection", "()Z",
-     reinterpret_cast<void*>(
-         android_location_GnssMeasurementsProvider_stop_measurement_collection)},
+            reinterpret_cast<void*>(
+            android_location_GnssMeasurementsProvider_stop_measurement_collection)},
+};
+
+static const JNINativeMethod sMeasurementCorrectionsMethods[] = {
+    /* name, signature, funcPtr */
+    {"native_is_measurement_corrections_supported", "()Z",
+            reinterpret_cast<void*>(
+            android_location_GnssMeasurementCorrectionsProvider_is_measurement_corrections_supported)},
     {"native_inject_gnss_measurement_corrections",
-     "(Landroid/location/GnssMeasurementCorrections;)Z",
-     reinterpret_cast<void*>(
-         android_location_GnssMeasurementsProvider_inject_gnss_measurement_corrections)},
+            "(Landroid/location/GnssMeasurementCorrections;)Z",
+            reinterpret_cast<void*>(
+            android_location_GnssMeasurementCorrectionsProvider_inject_gnss_measurement_corrections)},
 };
 
 static const JNINativeMethod sNavigationMessageMethods[] = {
@@ -2992,6 +3050,11 @@
             NELEM(sMeasurementMethods));
     jniRegisterNativeMethods(
             env,
+            "com/android/server/location/GnssMeasurementCorrectionsProvider",
+            sMeasurementCorrectionsMethods,
+            NELEM(sMeasurementCorrectionsMethods));
+    jniRegisterNativeMethods(
+            env,
             "com/android/server/location/GnssNavigationMessageProvider",
             sNavigationMessageMethods,
             NELEM(sNavigationMessageMethods));
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index 6386b3b3..7c91b64 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -15,7 +15,10 @@
  */
 package com.android.server;
 
+import static android.app.AlarmManager.ELAPSED_REALTIME;
 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
+import static android.app.AlarmManager.RTC;
+import static android.app.AlarmManager.RTC_WAKEUP;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
@@ -254,14 +257,22 @@
     }
 
     private void setTestAlarm(int type, long triggerTime, PendingIntent operation) {
+        setTestAlarm(type, triggerTime, operation, TEST_CALLING_UID);
+    }
+
+    private void setTestAlarm(int type, long triggerTime, PendingIntent operation, int callingUid) {
         mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, 0,
                 operation, null, "test", AlarmManager.FLAG_STANDALONE, null, null,
-                TEST_CALLING_UID, TEST_CALLING_PACKAGE);
+                callingUid, TEST_CALLING_PACKAGE);
     }
 
     private PendingIntent getNewMockPendingIntent() {
+        return getNewMockPendingIntent(TEST_CALLING_UID);
+    }
+
+    private PendingIntent getNewMockPendingIntent(int mockUid) {
         final PendingIntent mockPi = mock(PendingIntent.class, Answers.RETURNS_DEEP_STUBS);
-        when(mockPi.getCreatorUid()).thenReturn(TEST_CALLING_UID);
+        when(mockPi.getCreatorUid()).thenReturn(mockUid);
         when(mockPi.getCreatorPackage()).thenReturn(TEST_CALLING_PACKAGE);
         return mockPi;
     }
@@ -724,6 +735,91 @@
         verify(mMockContext).sendBroadcastAsUser(mService.mTimeTickIntent, UserHandle.ALL);
     }
 
+    @Test
+    public void alarmCountKeyedOnCallingUid() {
+        final int mockCreatorUid = 431412;
+        final PendingIntent pi = getNewMockPendingIntent(mockCreatorUid);
+        setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 5, pi);
+        assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        assertEquals(-1, mService.mAlarmsPerUid.get(mockCreatorUid, -1));
+    }
+
+    @Test
+    public void alarmCountOnSet() {
+        final int numAlarms = 103;
+        final int[] types = {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
+        for (int i = 1; i <= numAlarms; i++) {
+            setTestAlarm(types[i % 4], mNowElapsedTest + i, getNewMockPendingIntent());
+            assertEquals(i, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        }
+    }
+
+    @Test
+    public void alarmCountOnExpiration() throws InterruptedException {
+        final int numAlarms = 8; // This test is slow
+        for (int i = 0; i < numAlarms; i++) {
+            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent());
+        }
+        int expired = 0;
+        while (expired < numAlarms) {
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+            expired++;
+            assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
+        }
+    }
+
+    @Test
+    public void alarmCountOnUidRemoved() {
+        final int numAlarms = 10;
+        for (int i = 0; i < numAlarms; i++) {
+            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent());
+        }
+        assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        mService.removeLocked(TEST_CALLING_UID);
+        assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
+    }
+
+    @Test
+    public void alarmCountOnPackageRemoved() {
+        final int numAlarms = 10;
+        for (int i = 0; i < numAlarms; i++) {
+            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent());
+        }
+        assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        mService.removeLocked(TEST_CALLING_PACKAGE);
+        assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
+    }
+
+    @Test
+    public void alarmCountOnUserRemoved() {
+        final int mockUserId = 15;
+        final int numAlarms = 10;
+        for (int i = 0; i < numAlarms; i++) {
+            int mockUid = UserHandle.getUid(mockUserId, 1234 + i);
+            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10,
+                    getNewMockPendingIntent(mockUid), mockUid);
+        }
+        assertEquals(numAlarms, mService.mAlarmsPerUid.size());
+        mService.removeUserLocked(mockUserId);
+        assertEquals(0, mService.mAlarmsPerUid.size());
+    }
+
+    @Test
+    public void alarmCountOnAlarmRemoved() {
+        final int numAlarms = 10;
+        final PendingIntent[] pis = new PendingIntent[numAlarms];
+        for (int i = 0; i < numAlarms; i++) {
+            pis[i] = getNewMockPendingIntent();
+            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 5, pis[i]);
+        }
+        assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        for (int i = 0; i < numAlarms; i++) {
+            mService.removeLocked(pis[i], null);
+            assertEquals(numAlarms - i - 1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
+        }
+    }
+
     @After
     public void tearDown() {
         if (mMockingSession != null) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
index 1e02a12..329af95 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
@@ -38,9 +38,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 
 import android.app.AppOpsManager;
-import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
-import android.content.Context;
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.os.Handler;
@@ -50,7 +48,6 @@
 import android.util.Log;
 import android.view.IWindowManager;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import com.android.server.am.AssistDataRequester;
@@ -88,12 +85,10 @@
     private static final int TEST_UID = 0;
     private static final String TEST_PACKAGE = "";
 
-    private Context mContext;
     private AssistDataRequester mDataRequester;
     private Callbacks mCallbacks;
     private Object mCallbacksLock;
     private Handler mHandler;
-    private IActivityManager mAm;
     private IActivityTaskManager mAtm;
     private IWindowManager mWm;
     private AppOpsManager mAppOpsManager;
@@ -109,7 +104,6 @@
 
     @Before
     public void setUp() throws Exception {
-        mAm = mock(IActivityManager.class);
         mAtm = mock(IActivityTaskManager.class);
         mWm = mock(IWindowManager.class);
         mAppOpsManager = mock(AppOpsManager.class);
@@ -118,7 +112,7 @@
         mCallbacks = new Callbacks();
         mDataRequester = new AssistDataRequester(mContext, mWm, mAppOpsManager, mCallbacks,
                 mCallbacksLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT);
-
+        mDataRequester.mActivityTaskManager = mAtm;
         // Gate the continuation of the assist data callbacks until we are ready within the tests
         mGate = new CountDownLatch(1);
         doAnswer(invocation -> {
@@ -155,7 +149,6 @@
                 .checkOpNoThrow(eq(OP_ASSIST_SCREENSHOT), anyInt(), anyString());
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testRequestData() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -176,7 +169,6 @@
         assertReceivedDataCount(0, 0, 0, 0);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testCurrentAppDisallow_expectNullCallbacks() throws Exception {
         setupMocks(!CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -187,7 +179,6 @@
         assertReceivedDataCount(0, 1, 0, 1);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testProcessPendingData() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -245,7 +236,6 @@
         assertReceivedDataCount(0, 1, 0, 1);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testDisallowAssistContextExtras_expectNullDataCallbacks() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -259,7 +249,6 @@
         assertReceivedDataCount(0, 1, 0, 1);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testNoFetchScreenshots_expectNoScreenshotCallbacks() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -270,7 +259,6 @@
         assertReceivedDataCount(5, 5, 0, 0);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testDisallowAssistScreenshot_expectNullScreenshotCallback() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 17e2e90..30dcaa0 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -53,6 +53,9 @@
  *   <li>Operator name, short name and numeric id
  *   <li>Network selection mode
  * </ul>
+ *
+ * For historical reasons this class is not declared as final; however,
+ * it should be treated as though it were final.
  */
 public class ServiceState implements Parcelable {