Merge "Properly check for null pointers"
diff --git a/Android.bp b/Android.bp
index 9ffdd1d..21552695 100644
--- a/Android.bp
+++ b/Android.bp
@@ -203,7 +203,6 @@
     name: "framework-non-updatable-sources",
     srcs: [
         // Java/AIDL sources under frameworks/base
-        ":framework-appsearch-sources",
         ":framework-blobstore-sources",
         ":framework-core-sources",
         ":framework-drm-sources",
@@ -262,6 +261,7 @@
 filegroup {
     name: "framework-updatable-sources",
     srcs: [
+        ":framework-appsearch-sources",
         ":framework-sdkext-sources",
         ":framework-statsd-sources",
         ":updatable-media-srcs",
@@ -427,6 +427,7 @@
     defaults: ["framework-defaults"],
     srcs: [":framework-non-updatable-sources"],
     libs: [
+        "framework-appsearch-stubs",
         // TODO(b/146167933): Use framework-statsd-stubs
         "framework-statsd",
         "framework-wifi-stubs",
@@ -466,6 +467,7 @@
     installable: false, // this lib is a build-only library
     static_libs: [
         "framework-minus-apex",
+        "framework-appsearch", // TODO(b/146218515): should be framework-appsearch-stubs
         "framework-sdkext-stubs-systemapi",
         // TODO(b/146167933): Use framework-statsd-stubs instead.
         "framework-statsd",
diff --git a/apex/appsearch/Android.bp b/apex/appsearch/Android.bp
index bcdcc7d..b014fdc 100644
--- a/apex/appsearch/Android.bp
+++ b/apex/appsearch/Android.bp
@@ -14,9 +14,11 @@
 
 apex {
     name: "com.android.appsearch",
-
     manifest: "apex_manifest.json",
-
+    java_libs: [
+        "framework-appsearch",
+        "service-appsearch",
+    ],
     key: "com.android.appsearch.key",
     certificate: ":com.android.appsearch.certificate",
 }
diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp
index 0a65f73..3dc5a2c 100644
--- a/apex/appsearch/framework/Android.bp
+++ b/apex/appsearch/framework/Android.bp
@@ -23,17 +23,52 @@
 
 java_library {
   name: "framework-appsearch",
-  installable: false,
-  sdk_version: "core_platform",
-  srcs: [
-    ":framework-appsearch-sources",
-  ],
-  aidl: {
-    export_include_dirs: [
-      "java",
-    ],
-  },
+  installable: true,
+  sdk_version: "core_platform", // TODO(b/146218515) should be core_current
+  srcs: [":framework-appsearch-sources"],
   libs: [
-    "framework-minus-apex",
+    "framework-minus-apex",  // TODO(b/146218515) should be framework-system-stubs
   ],
 }
+
+metalava_appsearch_docs_args =
+    "--hide-package com.android.server " +
+    "--error UnhiddenSystemApi " +
+    "--hide RequiresPermission " +
+    "--hide MissingPermission " +
+    "--hide BroadcastBehavior " +
+    "--hide HiddenSuperclass " +
+    "--hide DeprecationMismatch " +
+    "--hide UnavailableSymbol " +
+    "--hide SdkConstant " +
+    "--hide HiddenTypeParameter " +
+    "--hide Todo --hide Typo " +
+    "--hide HiddenTypedefConstant " +
+    "--show-annotation android.annotation.SystemApi "
+
+droidstubs {
+    name: "framework-appsearch-stubs-srcs",
+    srcs: [
+        ":framework-annotations",
+        ":framework-appsearch-sources",
+    ],
+    aidl: {
+        include_dirs: ["frameworks/base/core/java"],
+    },
+    args: metalava_appsearch_docs_args,
+    sdk_version: "core_current",
+    libs: ["android_system_stubs_current"],
+}
+
+java_library {
+    name: "framework-appsearch-stubs",
+    srcs: [":framework-appsearch-stubs-srcs"],
+    aidl: {
+        export_include_dirs: [
+            "java",
+        ],
+    },
+    sdk_version: "core_current",
+    libs: ["android_system_stubs_current"],
+    installable: false,
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java
index fcebe3d..02cc967 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java
@@ -15,19 +15,25 @@
  */
 package android.app.appsearch;
 
+import android.annotation.SystemApi;
 import android.app.SystemServiceRegistry;
 import android.content.Context;
 
 /**
- * This is where the AppSearchManagerService wrapper is registered.
+ * Class holding initialization code for the AppSearch module.
  *
- * TODO(b/142567528): add comments when implement this class
  * @hide
  */
+@SystemApi
 public class AppSearchManagerFrameworkInitializer {
+    private AppSearchManagerFrameworkInitializer() {}
 
     /**
-     * TODO(b/142567528): add comments when implement this class
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers all AppSearch
+     * services to {@link Context}, so that {@link Context#getSystemService} can return them.
+     *
+     * @throws IllegalStateException if this is called from anywhere besides
+     *     {@link SystemServiceRegistry}
      */
     public static void initialize() {
         SystemServiceRegistry.registerStaticService(
diff --git a/api/current.txt b/api/current.txt
index d4255c8..4708616 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -38713,6 +38713,10 @@
 
   public final class MediaStore {
     ctor public MediaStore();
+    method @NonNull public static android.app.PendingIntent createDeleteRequest(@NonNull android.content.ContentResolver, @NonNull java.util.Collection<android.net.Uri>);
+    method @NonNull public static android.app.PendingIntent createFavoriteRequest(@NonNull android.content.ContentResolver, @NonNull java.util.Collection<android.net.Uri>, boolean);
+    method @NonNull public static android.app.PendingIntent createTrashRequest(@NonNull android.content.ContentResolver, @NonNull java.util.Collection<android.net.Uri>, boolean);
+    method @NonNull public static android.app.PendingIntent createWriteRequest(@NonNull android.content.ContentResolver, @NonNull java.util.Collection<android.net.Uri>);
     method @Nullable public static android.net.Uri getDocumentUri(@NonNull android.content.Context, @NonNull android.net.Uri);
     method @NonNull public static java.util.Set<java.lang.String> getExternalVolumeNames(@NonNull android.content.Context);
     method public static android.net.Uri getMediaScannerUri();
@@ -38723,9 +38727,6 @@
     method @NonNull public static String getVolumeName(@NonNull android.net.Uri);
     method @Deprecated @NonNull public static android.net.Uri setIncludePending(@NonNull android.net.Uri);
     method @NonNull public static android.net.Uri setRequireOriginal(@NonNull android.net.Uri);
-    method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);
-    method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long);
-    method public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri);
     field public static final String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
     field public static final String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
     field public static final String ACTION_REVIEW = "android.provider.action.REVIEW";
@@ -45233,6 +45234,7 @@
     method public void onDataConnectionStateChanged(int);
     method public void onDataConnectionStateChanged(int, int);
     method public void onMessageWaitingIndicatorChanged(boolean);
+    method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
     method public void onServiceStateChanged(android.telephony.ServiceState);
     method @Deprecated public void onSignalStrengthChanged(int);
     method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
@@ -45247,12 +45249,23 @@
     field public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000
     field public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4
     field public static final int LISTEN_NONE = 0; // 0x0
+    field @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
     field public static final int LISTEN_SERVICE_STATE = 1; // 0x1
     field @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 2; // 0x2
     field public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100
     field public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000
   }
 
+  public final class PreciseDataConnectionState implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getLastCauseCode();
+    method @Nullable public android.net.LinkProperties getLinkProperties();
+    method public int getNetworkType();
+    method public int getState();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR;
+  }
+
   public final class RadioAccessSpecifier implements android.os.Parcelable {
     ctor public RadioAccessSpecifier(int, int[], int[]);
     method public int describeContents();
@@ -45765,6 +45778,7 @@
     field public static final int DATA_CONNECTED = 2; // 0x2
     field public static final int DATA_CONNECTING = 1; // 0x1
     field public static final int DATA_DISCONNECTED = 0; // 0x0
+    field public static final int DATA_DISCONNECTING = 4; // 0x4
     field public static final int DATA_SUSPENDED = 3; // 0x3
     field public static final int DATA_UNKNOWN = -1; // 0xffffffff
     field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT";
diff --git a/api/removed.txt b/api/removed.txt
index 1a2f434..4e8e325 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -441,6 +441,9 @@
     method @Deprecated public static boolean getIncludePending(@NonNull android.net.Uri);
     method @Deprecated @NonNull public static android.provider.MediaStore.PendingSession openPending(@NonNull android.content.Context, @NonNull android.net.Uri);
     method @Deprecated @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
+    method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);
+    method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long);
+    method @Deprecated public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri);
   }
 
   public static interface MediaStore.Audio.AudioColumns extends android.provider.MediaStore.MediaColumns {
diff --git a/api/system-current.txt b/api/system-current.txt
index 7504582..b14bf34 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -811,6 +811,14 @@
 
 }
 
+package android.app.appsearch {
+
+  public class AppSearchManagerFrameworkInitializer {
+    method public static void initialize();
+  }
+
+}
+
 package android.app.assist {
 
   public static class AssistStructure.ViewNode {
@@ -8039,6 +8047,7 @@
     field public static final String KEY_CONTEXTUAL_ACTIONS = "key_contextual_actions";
     field public static final String KEY_IMPORTANCE = "key_importance";
     field public static final String KEY_PEOPLE = "key_people";
+    field public static final String KEY_RANKING_SCORE = "key_ranking_score";
     field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
     field public static final String KEY_TEXT_REPLIES = "key_text_replies";
     field public static final String KEY_USER_SENTIMENT = "key_user_sentiment";
@@ -9320,7 +9329,6 @@
     method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
     method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
     method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
-    method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
     method public void onRadioPowerStateChanged(int);
     method public void onSrvccStateChanged(int);
     method public void onVoiceActivationStateChanged(int);
@@ -9330,7 +9338,6 @@
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
     field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
-    field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
     field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
     field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
     field public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
@@ -9356,13 +9363,12 @@
   }
 
   public final class PreciseDataConnectionState implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public String getDataConnectionApn();
-    method public int getDataConnectionApnTypeBitMask();
-    method public int getDataConnectionFailCause();
-    method public int getDataConnectionState();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR;
+    method @Deprecated @NonNull public String getDataConnectionApn();
+    method @Deprecated public int getDataConnectionApnTypeBitMask();
+    method @Deprecated public int getDataConnectionFailCause();
+    method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
+    method @Deprecated public int getDataConnectionNetworkType();
+    method @Deprecated public int getDataConnectionState();
   }
 
   public final class PreciseDisconnectCause {
diff --git a/api/test-current.txt b/api/test-current.txt
index 3bdd479..1c6bce0 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2832,6 +2832,7 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
     field public static final String KEY_CONTEXTUAL_ACTIONS = "key_contextual_actions";
     field public static final String KEY_IMPORTANCE = "key_importance";
+    field public static final String KEY_RANKING_SCORE = "key_ranking_score";
     field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
     field public static final String KEY_TEXT_REPLIES = "key_text_replies";
     field public static final String KEY_USER_SENTIMENT = "key_user_sentiment";
@@ -3162,6 +3163,10 @@
     field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
   }
 
+  public final class PreciseDataConnectionState implements android.os.Parcelable {
+    ctor @Deprecated public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int);
+  }
+
   public class ServiceState implements android.os.Parcelable {
     method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo);
     method public void setCdmaSystemAndNetworkId(int, int);
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index f4e465a..0f10c39 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -1943,35 +1943,6 @@
     }
 
     /**
-     * @hide
-     * Removes the shared account.
-     * @param account the account to remove
-     * @param user the user to remove the account from
-     * @return
-     */
-    public boolean removeSharedAccount(final Account account, UserHandle user) {
-        try {
-            boolean val = mService.removeSharedAccountAsUser(account, user.getIdentifier());
-            return val;
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * @hide
-     * @param user
-     * @return
-     */
-    public Account[] getSharedAccounts(UserHandle user) {
-        try {
-            return mService.getSharedAccountsAsUser(user.getIdentifier());
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Confirms that the user knows the password for an account to make extra
      * sure they are the owner of the account.  The user-entered password can
      * be supplied directly, otherwise the authenticator for this account type
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 4cf0a20..0127138 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -80,14 +80,11 @@
         String authTokenType);
 
     /* Shared accounts */
-    Account[] getSharedAccountsAsUser(int userId);
-    boolean removeSharedAccountAsUser(in Account account, int userId);
     void addSharedAccountsFromParentUser(int parentUserId, int userId, String opPackageName);
 
     /* Account renaming. */
     void renameAccount(in IAccountManagerResponse response, in Account accountToRename, String newName);
     String getPreviousName(in Account account);
-    boolean renameSharedAccountAsUser(in Account accountToRename, String newName, int userId);
 
     /* Add account in two steps. */
     void startAddAccountSession(in IAccountManagerResponse response, String accountType,
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 725e0fb..5e478b5 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -44,70 +44,10 @@
  * <p>
  * <b>Device battery life will be significantly affected by the use of this API.</b>
  * Do not acquire {@link WakeLock}s unless you really need them, use the minimum levels
- * possible, and be sure to release them as soon as possible.
- * </p><p>
- * The primary API you'll use is {@link #newWakeLock(int, String) newWakeLock()}.
- * This will create a {@link PowerManager.WakeLock} object.  You can then use methods
- * on the wake lock object to control the power state of the device.
- * </p><p>
- * In practice it's quite simple:
- * {@samplecode
- * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- * PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
- * wl.acquire();
- *   ..screen will stay on during this section..
- * wl.release();
- * }
- * </p><p>
- * The following wake lock levels are defined, with varying effects on system power.
- * <i>These levels are mutually exclusive - you may only specify one of them.</i>
+ * possible, and be sure to release them as soon as possible. In most cases,
+ * you'll want to use
+ * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead.
  *
- * <table>
- *     <tr><th>Flag Value</th>
- *     <th>CPU</th> <th>Screen</th> <th>Keyboard</th></tr>
- *
- *     <tr><td>{@link #PARTIAL_WAKE_LOCK}</td>
- *         <td>On*</td> <td>Off</td> <td>Off</td>
- *     </tr>
- *
- *     <tr><td>{@link #SCREEN_DIM_WAKE_LOCK}</td>
- *         <td>On</td> <td>Dim</td> <td>Off</td>
- *     </tr>
- *
- *     <tr><td>{@link #SCREEN_BRIGHT_WAKE_LOCK}</td>
- *         <td>On</td> <td>Bright</td> <td>Off</td>
- *     </tr>
- *
- *     <tr><td>{@link #FULL_WAKE_LOCK}</td>
- *         <td>On</td> <td>Bright</td> <td>Bright</td>
- *     </tr>
- * </table>
- * </p><p>
- * *<i>If you hold a partial wake lock, the CPU will continue to run, regardless of any
- * display timeouts or the state of the screen and even after the user presses the power button.
- * In all other wake locks, the CPU will run, but the user can still put the device to sleep
- * using the power button.</i>
- * </p><p>
- * In addition, you can add two more flags, which affect behavior of the screen only.
- * <i>These flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}.</i></p>
- *
- * <table>
- *     <tr><th>Flag Value</th> <th>Description</th></tr>
- *
- *     <tr><td>{@link #ACQUIRE_CAUSES_WAKEUP}</td>
- *         <td>Normal wake locks don't actually turn on the illumination.  Instead, they cause
- *         the illumination to remain on once it turns on (e.g. from user activity).  This flag
- *         will force the screen and/or keyboard to turn on immediately, when the WakeLock is
- *         acquired.  A typical use would be for notifications which are important for the user to
- *         see immediately.</td>
- *     </tr>
- *
- *     <tr><td>{@link #ON_AFTER_RELEASE}</td>
- *         <td>If this flag is set, the user activity timer will be reset when the WakeLock is
- *         released, causing the illumination to remain on a bit longer.  This can be used to
- *         reduce flicker if you are cycling between wake lock conditions.</td>
- *     </tr>
- * </table>
  * <p>
  * Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK}
  * permission in an {@code <uses-permission>} element of the application's manifest.
@@ -931,7 +871,8 @@
      * {@link #FULL_WAKE_LOCK}, {@link #SCREEN_DIM_WAKE_LOCK}
      * and {@link #SCREEN_BRIGHT_WAKE_LOCK}.  Exactly one wake lock level must be
      * specified as part of the {@code levelAndFlags} parameter.
-     * </p><p>
+     * </p>
+     * <p>
      * The wake lock flags are: {@link #ACQUIRE_CAUSES_WAKEUP}
      * and {@link #ON_AFTER_RELEASE}.  Multiple flags can be combined as part of the
      * {@code levelAndFlags} parameters.
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 2fa3386..701ba91 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -32,6 +32,7 @@
 import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.AppGlobals;
+import android.app.PendingIntent;
 import android.content.ClipData;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
@@ -86,6 +87,7 @@
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
@@ -162,6 +164,15 @@
     /** {@hide} */
     public static final String SUICIDE_CALL = "suicide";
 
+    /** {@hide} */
+    public static final String CREATE_WRITE_REQUEST_CALL = "create_write_request";
+    /** {@hide} */
+    public static final String CREATE_TRASH_REQUEST_CALL = "create_trash_request";
+    /** {@hide} */
+    public static final String CREATE_FAVORITE_REQUEST_CALL = "create_favorite_request";
+    /** {@hide} */
+    public static final String CREATE_DELETE_REQUEST_CALL = "create_delete_request";
+
     /**
      * Extra used with {@link #SCAN_FILE_CALL} or {@link #SCAN_VOLUME_CALL} to indicate that
      * the file path originated from shell.
@@ -199,6 +210,13 @@
     /** {@hide} */
     public static final String DELETE_CONTRIBUTED_MEDIA_CALL = "delete_contributed_media";
 
+    /** {@hide} */
+    public static final String EXTRA_CLIP_DATA = "clip_data";
+    /** {@hide} */
+    public static final String EXTRA_CONTENT_VALUES = "content_values";
+    /** {@hide} */
+    public static final String EXTRA_RESULT = "result";
+
     /**
      * This is for internal use by the media scanner only.
      * Name of the (optional) Uri parameter that determines whether to skip deleting
@@ -606,6 +624,10 @@
      * {@link ContentResolver#delete}.
      * <p>
      * By default, trashed items are filtered away from operations.
+     *
+     * @see MediaColumns#IS_TRASHED
+     * @see MediaStore#QUERY_ARG_MATCH_TRASHED
+     * @see MediaStore#createTrashRequest
      */
     @Match
     public static final String QUERY_ARG_MATCH_TRASHED = "android:query-arg-match-trashed";
@@ -620,6 +642,10 @@
      * <p>
      * By default, favorite items are <em>not</em> filtered away from
      * operations.
+     *
+     * @see MediaColumns#IS_FAVORITE
+     * @see MediaStore#QUERY_ARG_MATCH_FAVORITE
+     * @see MediaStore#createFavoriteRequest
      */
     @Match
     public static final String QUERY_ARG_MATCH_FAVORITE = "android:query-arg-match-favorite";
@@ -952,7 +978,9 @@
      * @see MediaStore#setIncludeTrashed(Uri)
      * @see MediaStore#trash(Context, Uri)
      * @see MediaStore#untrash(Context, Uri)
+     * @removed
      */
+    @Deprecated
     public static void trash(@NonNull Context context, @NonNull Uri uri) {
         trash(context, uri, 48 * DateUtils.HOUR_IN_MILLIS);
     }
@@ -970,7 +998,9 @@
      * @see MediaStore#setIncludeTrashed(Uri)
      * @see MediaStore#trash(Context, Uri)
      * @see MediaStore#untrash(Context, Uri)
+     * @removed
      */
+    @Deprecated
     public static void trash(@NonNull Context context, @NonNull Uri uri,
             @DurationMillisLong long timeoutMillis) {
         if (timeoutMillis < 0) {
@@ -992,7 +1022,9 @@
      * @see MediaStore#setIncludeTrashed(Uri)
      * @see MediaStore#trash(Context, Uri)
      * @see MediaStore#untrash(Context, Uri)
+     * @removed
      */
+    @Deprecated
     public static void untrash(@NonNull Context context, @NonNull Uri uri) {
         final ContentValues values = new ContentValues();
         values.put(MediaColumns.IS_TRASHED, 0);
@@ -1010,6 +1042,180 @@
         return uri.buildUpon().authority(MediaStore.AUTHORITY_LEGACY).build();
     }
 
+    private static @NonNull PendingIntent createRequest(@NonNull ContentResolver resolver,
+            @NonNull String method, @NonNull Collection<Uri> uris, @Nullable ContentValues values) {
+        Objects.requireNonNull(resolver);
+        Objects.requireNonNull(uris);
+
+        final Iterator<Uri> it = uris.iterator();
+        final ClipData clipData = ClipData.newRawUri(null, it.next());
+        while (it.hasNext()) {
+            clipData.addItem(new ClipData.Item(it.next()));
+        }
+
+        final Bundle extras = new Bundle();
+        extras.putParcelable(EXTRA_CLIP_DATA, clipData);
+        extras.putParcelable(EXTRA_CONTENT_VALUES, values);
+        return resolver.call(AUTHORITY, method, null, extras).getParcelable(EXTRA_RESULT);
+    }
+
+    /**
+     * Create a {@link PendingIntent} that will prompt the user to grant your
+     * app write access for the requested media items.
+     * <p>
+     * This call only generates the request for a prompt; to display the prompt,
+     * call {@link Activity#startIntentSenderForResult} with
+     * {@link PendingIntent#getIntentSender()}. You can then determine if the
+     * user granted your request by testing for {@link Activity#RESULT_OK} in
+     * {@link Activity#onActivityResult}.
+     * <p>
+     * Permissions granted through this mechanism are tied to the lifecycle of
+     * the {@link Activity} that requests them. If you need to retain
+     * longer-term access for background actions, you can place items into a
+     * {@link ClipData} or {@link Intent} which can then be passed to
+     * {@link Context#startService} or
+     * {@link android.app.job.JobInfo.Builder#setClipData}. Be sure to include
+     * any relevant access modes you want to retain, such as
+     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
+     * <p>
+     * The displayed prompt will reflect all the media items you're requesting,
+     * including those for which you already hold write access. If you want to
+     * determine if you already hold write access before requesting access, use
+     * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
+     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
+     * <p>
+     * For security and performance reasons this method does not support
+     * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION} or
+     * {@link Intent#FLAG_GRANT_PREFIX_URI_PERMISSION}.
+     *
+     * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
+     *            Typically this value is {@link Context#getContentResolver()},
+     *            but if you need more explicit lifecycle controls, you can
+     *            obtain a {@link ContentProviderClient} and wrap it using
+     *            {@link ContentResolver#wrap(ContentProviderClient)}.
+     * @param uris The set of media items to include in this request. Each item
+     *            must be hosted by {@link MediaStore#AUTHORITY} and must
+     *            reference a specific media item by {@link BaseColumns#_ID}.
+     */
+    public static @NonNull PendingIntent createWriteRequest(@NonNull ContentResolver resolver,
+            @NonNull Collection<Uri> uris) {
+        return createRequest(resolver, CREATE_WRITE_REQUEST_CALL, uris, null);
+    }
+
+    /**
+     * Create a {@link PendingIntent} that will prompt the user to trash the
+     * requested media items. When the user approves this request,
+     * {@link MediaColumns#IS_TRASHED} is set on these items.
+     * <p>
+     * This call only generates the request for a prompt; to display the prompt,
+     * call {@link Activity#startIntentSenderForResult} with
+     * {@link PendingIntent#getIntentSender()}. You can then determine if the
+     * user granted your request by testing for {@link Activity#RESULT_OK} in
+     * {@link Activity#onActivityResult}.
+     * <p>
+     * The displayed prompt will reflect all the media items you're requesting,
+     * including those for which you already hold write access. If you want to
+     * determine if you already hold write access before requesting access, use
+     * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
+     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
+     *
+     * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
+     *            Typically this value is {@link Context#getContentResolver()},
+     *            but if you need more explicit lifecycle controls, you can
+     *            obtain a {@link ContentProviderClient} and wrap it using
+     *            {@link ContentResolver#wrap(ContentProviderClient)}.
+     * @param uris The set of media items to include in this request. Each item
+     *            must be hosted by {@link MediaStore#AUTHORITY} and must
+     *            reference a specific media item by {@link BaseColumns#_ID}.
+     * @param value The {@link MediaColumns#IS_TRASHED} value to apply.
+     * @see MediaColumns#IS_TRASHED
+     * @see MediaStore#QUERY_ARG_MATCH_TRASHED
+     */
+    public static @NonNull PendingIntent createTrashRequest(@NonNull ContentResolver resolver,
+            @NonNull Collection<Uri> uris, boolean value) {
+        final ContentValues values = new ContentValues();
+        if (value) {
+            values.put(MediaColumns.IS_TRASHED, 1);
+            values.put(MediaColumns.DATE_EXPIRES,
+                    (System.currentTimeMillis() + DateUtils.WEEK_IN_MILLIS) / 1000);
+        } else {
+            values.put(MediaColumns.IS_TRASHED, 0);
+            values.putNull(MediaColumns.DATE_EXPIRES);
+        }
+        return createRequest(resolver, CREATE_TRASH_REQUEST_CALL, uris, values);
+    }
+
+    /**
+     * Create a {@link PendingIntent} that will prompt the user to favorite the
+     * requested media items. When the user approves this request,
+     * {@link MediaColumns#IS_FAVORITE} is set on these items.
+     * <p>
+     * This call only generates the request for a prompt; to display the prompt,
+     * call {@link Activity#startIntentSenderForResult} with
+     * {@link PendingIntent#getIntentSender()}. You can then determine if the
+     * user granted your request by testing for {@link Activity#RESULT_OK} in
+     * {@link Activity#onActivityResult}.
+     * <p>
+     * The displayed prompt will reflect all the media items you're requesting,
+     * including those for which you already hold write access. If you want to
+     * determine if you already hold write access before requesting access, use
+     * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
+     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
+     *
+     * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
+     *            Typically this value is {@link Context#getContentResolver()},
+     *            but if you need more explicit lifecycle controls, you can
+     *            obtain a {@link ContentProviderClient} and wrap it using
+     *            {@link ContentResolver#wrap(ContentProviderClient)}.
+     * @param uris The set of media items to include in this request. Each item
+     *            must be hosted by {@link MediaStore#AUTHORITY} and must
+     *            reference a specific media item by {@link BaseColumns#_ID}.
+     * @param value The {@link MediaColumns#IS_FAVORITE} value to apply.
+     * @see MediaColumns#IS_FAVORITE
+     * @see MediaStore#QUERY_ARG_MATCH_FAVORITE
+     */
+    public static @NonNull PendingIntent createFavoriteRequest(@NonNull ContentResolver resolver,
+            @NonNull Collection<Uri> uris, boolean value) {
+        final ContentValues values = new ContentValues();
+        if (value) {
+            values.put(MediaColumns.IS_FAVORITE, 1);
+        } else {
+            values.put(MediaColumns.IS_FAVORITE, 0);
+        }
+        return createRequest(resolver, CREATE_FAVORITE_REQUEST_CALL, uris, values);
+    }
+
+    /**
+     * Create a {@link PendingIntent} that will prompt the user to permanently
+     * delete the requested media items. When the user approves this request,
+     * {@link ContentResolver#delete} will be called on these items.
+     * <p>
+     * This call only generates the request for a prompt; to display the prompt,
+     * call {@link Activity#startIntentSenderForResult} with
+     * {@link PendingIntent#getIntentSender()}. You can then determine if the
+     * user granted your request by testing for {@link Activity#RESULT_OK} in
+     * {@link Activity#onActivityResult}.
+     * <p>
+     * The displayed prompt will reflect all the media items you're requesting,
+     * including those for which you already hold write access. If you want to
+     * determine if you already hold write access before requesting access, use
+     * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
+     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
+     *
+     * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
+     *            Typically this value is {@link Context#getContentResolver()},
+     *            but if you need more explicit lifecycle controls, you can
+     *            obtain a {@link ContentProviderClient} and wrap it using
+     *            {@link ContentResolver#wrap(ContentProviderClient)}.
+     * @param uris The set of media items to include in this request. Each item
+     *            must be hosted by {@link MediaStore#AUTHORITY} and must
+     *            reference a specific media item by {@link BaseColumns#_ID}.
+     */
+    public static @NonNull PendingIntent createDeleteRequest(@NonNull ContentResolver resolver,
+            @NonNull Collection<Uri> uris) {
+        return createRequest(resolver, CREATE_DELETE_REQUEST_CALL, uris, null);
+    }
+
     /**
      * Common media metadata columns.
      */
@@ -1127,9 +1333,9 @@
          * Trashed items are retained until they expire as defined by
          * {@link #DATE_EXPIRES}.
          *
+         * @see MediaColumns#IS_TRASHED
          * @see MediaStore#QUERY_ARG_MATCH_TRASHED
-         * @see MediaStore#trash(Context, Uri)
-         * @see MediaStore#untrash(Context, Uri)
+         * @see MediaStore#createTrashRequest
          */
         @Column(Cursor.FIELD_TYPE_INTEGER)
         public static final String IS_TRASHED = "is_trashed";
@@ -1302,7 +1508,9 @@
          * Flag indicating if the media item has been marked as being a
          * "favorite" by the user.
          *
+         * @see MediaColumns#IS_FAVORITE
          * @see MediaStore#QUERY_ARG_MATCH_FAVORITE
+         * @see MediaStore#createFavoriteRequest
          */
         @Column(Cursor.FIELD_TYPE_INTEGER)
         public static final String IS_FAVORITE = "is_favorite";
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 8ab687f..c84fbc7 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -124,6 +124,13 @@
     public static final String KEY_IMPORTANCE = "key_importance";
 
     /**
+     * Data type: float, a ranking score from 0 (lowest) to 1 (highest).
+     * Used to rank notifications inside that fall under the same classification (i.e. alerting,
+     * silenced).
+     */
+    public static final String KEY_RANKING_SCORE = "key_ranking_score";
+
+    /**
      * Create a notification adjustment.
      *
      * @param pkg The package of the notification.
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 716a522..e3f11a1 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -35,8 +35,8 @@
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
 
-import com.android.internal.telephony.IPhoneStateListener;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.IPhoneStateListener;
 
 import dalvik.system.VMRuntime;
 
@@ -196,12 +196,13 @@
     /**
      * Listen for {@link PreciseDataConnectionState} on the data connection (cellular).
      *
-     * @see #onPreciseDataConnectionStateChanged
+     * <p>Requires permission {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
-     * @hide
+     * @see #onPreciseDataConnectionStateChanged
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
-    @SystemApi
+    @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
     public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE            = 0x00001000;
 
     /**
@@ -719,8 +720,9 @@
     }
 
     /**
-     * Callback invoked when data connection state changes with precise information
-     * on the registered subscription.
+     * Callback providing update about the default/internet data connection on the registered
+     * subscription.
+     *
      * Note, the registration subId comes from {@link TelephonyManager} object which registers
      * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}.
      * If this TelephonyManager object was created with
@@ -728,12 +730,13 @@
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
-     * @param dataConnectionState {@link PreciseDataConnectionState}
+     * <p>Requires permission {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
-     * @hide
+     * @param dataConnectionState {@link PreciseDataConnectionState}
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
-    @SystemApi
+    @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
     public void onPreciseDataConnectionStateChanged(
             @NonNull PreciseDataConnectionState dataConnectionState) {
         // default implementation empty
@@ -1042,11 +1045,21 @@
             PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
             if (psl == null) return;
 
-            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
-                    () -> {
-                        psl.onDataConnectionStateChanged(state, networkType);
-                        psl.onDataConnectionStateChanged(state);
-                    }));
+            if (state == TelephonyManager.DATA_DISCONNECTING
+                    && VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) {
+                Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                        () -> {
+                            psl.onDataConnectionStateChanged(
+                                    TelephonyManager.DATA_CONNECTED, networkType);
+                            psl.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED);
+                        }));
+            } else {
+                Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                        () -> {
+                            psl.onDataConnectionStateChanged(state, networkType);
+                            psl.onDataConnectionStateChanged(state);
+                        }));
+            }
         }
 
         public void onDataActivity(int direction) {
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 9d7b57b..b3702e6 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -21,17 +21,13 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.content.Context;
-import android.net.LinkProperties;
-import android.net.NetworkCapabilities;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.telephony.Annotation.ApnType;
 import android.telephony.Annotation.CallState;
 import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.DataFailureCause;
-import android.telephony.Annotation.DataState;
 import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.PreciseCallStates;
 import android.telephony.Annotation.RadioPowerState;
@@ -357,27 +353,18 @@
      * @param subId for which data connection state changed.
      * @param slotIndex for which data connections state changed. Can be derived from subId except
      * when subId is invalid.
-     * @param state latest data connection state, e.g,
-     * @param isDataConnectivityPossible indicates if data is allowed
-     * @param apn the APN {@link ApnSetting#getApnName()} of this data connection.
-     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN.
-     * @param linkProperties {@link LinkProperties} associated with this data connection.
-     * @param networkCapabilities {@link NetworkCapabilities} associated with this data connection.
-     * @param networkType associated with this data connection.
-     * @param roaming {@code true} indicates in roaming, {@false} otherwise.
-     * @see TelephonyManager#DATA_DISCONNECTED
-     * @see TelephonyManager#isDataConnectivityPossible()
+     * @param apnType the APN type that triggered this update
+     * @param preciseState the PreciseDataConnectionState
      *
+     * @see android.telephony.PreciseDataConnection
+     * @see TelephonyManager#DATA_DISCONNECTED
      * @hide
      */
-    public void notifyDataConnectionForSubscriber(int slotIndex, int subId, @DataState int state,
-        boolean isDataConnectivityPossible,
-        @ApnType String apn, String apnType, LinkProperties linkProperties,
-        NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
+    public void notifyDataConnectionForSubscriber(int slotIndex, int subId,
+            String apnType, PreciseDataConnectionState preciseState) {
         try {
-            sRegistry.notifyDataConnectionForSubscriber(slotIndex, subId, state,
-                isDataConnectivityPossible,
-                apn, apnType, linkProperties, networkCapabilities, networkType, roaming);
+            sRegistry.notifyDataConnectionForSubscriber(
+                    slotIndex, subId, apnType, preciseState);
         } catch (RemoteException ex) {
             // system process is dead
         }
@@ -662,25 +649,6 @@
     }
 
     /**
-     * Notify data connection failed on certain subscription.
-     *
-     * @param subId for which data connection failed.
-     * @param slotIndex for which data conenction faled. Can be derived from subId except when subId
-     * is invalid.
-     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. Note each data
-     * connection can support multiple anyTypes.
-     *
-     * @hide
-     */
-    public void notifyDataConnectionFailed(int subId, int slotIndex, String apnType) {
-        try {
-            sRegistry.notifyDataConnectionFailedForSubscriber(slotIndex, subId, apnType);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    /**
      * TODO change from bundle to CellLocation?
      * @hide
      */
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index d8e8d67..1c71b0a 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -24,6 +24,8 @@
 import android.telephony.CellInfo;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.PhoneCapability;
+import android.telephony.PhysicalChannelConfig;
+import android.telephony.PreciseDataConnectionState;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.emergency.EmergencyNumber;
@@ -60,11 +62,10 @@
     @UnsupportedAppUsage(maxTargetSdk = 28)
     void notifyDataActivity(int state);
     void notifyDataActivityForSubscriber(in int subId, int state);
-    void notifyDataConnectionForSubscriber(int phoneId, int subId, int state,
-            boolean isDataConnectivityPossible,
-            String apn, String apnType, in LinkProperties linkProperties,
-            in NetworkCapabilities networkCapabilities, int networkType, boolean roaming);
-    void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType);
+    void notifyDataConnectionForSubscriber(
+            int phoneId, int subId, String apnType, in PreciseDataConnectionState preciseState);
+    @UnsupportedAppUsage
+    void notifyDataConnectionFailed(String apnType);
     @UnsupportedAppUsage(maxTargetSdk = 28)
     void notifyCellLocation(in Bundle cellLocation);
     void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation);
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index bef0ee4..8c1ecae 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -33,6 +33,7 @@
 
 // Static whitelist of open paths that the zygote is allowed to keep open.
 static const char* kPathWhitelist[] = {
+  "/apex/com.android.appsearch/javalib/framework-appsearch.jar",
   "/apex/com.android.conscrypt/javalib/conscrypt.jar",
   "/apex/com.android.ipsec/javalib/ike.jar",
   "/apex/com.android.media/javalib/updatable-media.jar",
diff --git a/media/Android.bp b/media/Android.bp
index e2bdad1..4b50b7a 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -77,20 +77,13 @@
     path: "apex/java"
 }
 
-metalava_updatable_media_args = " --error UnhiddenSystemApi " +
-    "--hide RequiresPermission " +
-    "--hide MissingPermission --hide BroadcastBehavior " +
-    "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
-    "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo " +
-    "--hide HiddenTypedefConstant --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS,process=android.annotation.SystemApi.Process.ALL\\) "
-
 droidstubs {
     name: "updatable-media-stubs",
     srcs: [
         ":updatable-media-srcs",
         ":framework-media-annotation-srcs",
     ],
-    args: metalava_updatable_media_args,
+    defaults: [ "framework-module-stubs-defaults-systemapi" ],
     aidl: {
         // TODO(b/135922046) remove this
         include_dirs: ["frameworks/base/core/java"],
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 1277736..c82bc30 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -103,7 +103,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.function.Consumer;
 
 import javax.inject.Inject;
@@ -735,7 +734,7 @@
     @SuppressWarnings("FieldCanBeLocal")
     private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
         @Override
-        public void onPendingEntryAdded(NotificationEntry entry) {
+        public void onNotificationAdded(NotificationEntry entry) {
             boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey());
             boolean userBlocked = mUserBlockedBubbles.contains(entry.getKey());
             boolean wasAdjusted = BubbleExperimentConfig.adjustForExperiments(
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
index 21471ec..4c1cf49 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
@@ -32,6 +32,9 @@
 import android.content.Intent;
 import android.content.pm.LauncherApps;
 import android.content.pm.ShortcutInfo;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.Parcelable;
@@ -39,8 +42,11 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.people.PeopleHubNotificationListenerKt;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -227,15 +233,29 @@
         List<Person> personList = getPeopleFromNotification(entry);
         if (personList.size() > 0) {
             final Person person = personList.get(0);
-
             if (person != null) {
                 icon = person.getIcon();
+                if (icon == null) {
+                    // Lets try and grab the icon constructed by the layout
+                    Drawable d = PeopleHubNotificationListenerKt.extractAvatarFromRow(entry);
+                    if (d instanceof  BitmapDrawable) {
+                        icon = Icon.createWithBitmap(((BitmapDrawable) d).getBitmap());
+                    }
+                }
             }
         }
         if (icon == null) {
-            icon = notification.getLargeIcon() != null
-                    ? notification.getLargeIcon()
-                    : notification.getSmallIcon();
+            boolean shouldTint = notification.getLargeIcon() == null;
+            icon = shouldTint
+                    ? notification.getSmallIcon()
+                    : notification.getLargeIcon();
+            if (shouldTint) {
+                int notifColor = entry.getSbn().getNotification().color;
+                notifColor = ColorUtils.setAlphaComponent(notifColor, 255);
+                notifColor = ContrastColorUtil.findContrastColor(notifColor, Color.WHITE,
+                        true /* findFg */, 3f);
+                icon.setTint(notifColor);
+            }
         }
         if (intent != null) {
             return new Notification.BubbleMetadata.Builder()
@@ -285,7 +305,7 @@
     }
 
     static boolean isShortcutIntent(PendingIntent intent) {
-        return intent.equals(sDummyShortcutIntent);
+        return intent != null && intent.equals(sDummyShortcutIntent);
     }
 
     static List<Person> getPeopleFromNotification(NotificationEntry entry) {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
index 9f79785..077d260 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.UserHandle;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -97,7 +98,7 @@
             if (!mReceiverRegistered) {
                 mCurrentUserId = ActivityManager.getCurrentUser();
                 IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-                mBroadcastDispatcher.registerReceiver(this, filter);
+                mBroadcastDispatcher.registerReceiver(this, filter, null, UserHandle.ALL);
                 mReceiverRegistered = true;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt
index 987b52db..784673e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt
@@ -249,7 +249,7 @@
     }
 }
 
-private fun extractAvatarFromRow(entry: NotificationEntry): Drawable? =
+fun extractAvatarFromRow(entry: NotificationEntry): Drawable? =
         entry.row
                 ?.childrenWithId(R.id.expanded)
                 ?.mapNotNull { it as? ViewGroup }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index b8aea9b..4c5bbce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -561,7 +561,7 @@
     }
 
     protected void scheduleUpdate() {
-        if (mUpdatePending) return;
+        if (mUpdatePending || mScrimBehind == null) return;
 
         // Make sure that a frame gets scheduled.
         mScrimBehind.invalidate();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 2ccecec..2bf855a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -261,7 +261,7 @@
 
     @Test
     public void testRemoveBubble_withDismissedNotif() {
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
@@ -304,7 +304,7 @@
         assertFalse(mBubbleController.isStackExpanded());
 
         // Mark it as a bubble and add it explicitly
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         // We should have bubbles & their notifs should not be suppressed
@@ -334,8 +334,8 @@
     @Test
     public void testCollapseAfterChangingExpandedBubble() {
         // Mark it as a bubble and add it explicitly
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
-        mEntryListener.onPendingEntryAdded(mRow2.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow2.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
         mBubbleController.updateBubble(mRow2.getEntry());
 
@@ -377,7 +377,7 @@
     @Test
     public void testExpansionRemovesShowInShadeAndDot() {
         // Mark it as a bubble and add it explicitly
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         // We should have bubbles & their notifs should not be suppressed
@@ -403,7 +403,7 @@
     @Test
     public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
         // Mark it as a bubble and add it explicitly
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         // We should have bubbles & their notifs should not be suppressed
@@ -439,8 +439,8 @@
     @Test
     public void testRemoveLastExpandedCollapses() {
         // Mark it as a bubble and add it explicitly
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
-        mEntryListener.onPendingEntryAdded(mRow2.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow2.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
         mBubbleController.updateBubble(mRow2.getEntry());
         verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
@@ -483,7 +483,7 @@
                 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
 
         // Add the auto expand bubble
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         // Expansion shouldn't change
@@ -501,7 +501,7 @@
                 Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
 
         // Add the auto expand bubble
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         // Expansion should change
@@ -519,7 +519,7 @@
                 Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
 
         // Add the suppress notif bubble
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         // Notif should be suppressed because we were foreground
@@ -564,7 +564,7 @@
     public void testExpandStackAndSelectBubble_removedFirst() {
         final String key = mRow.getEntry().getKey();
 
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         // Simulate notification cancellation.
@@ -576,7 +576,7 @@
 
     @Test
     public void testMarkNewNotificationAsShowInShade() {
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
                 mRow.getEntry().getKey()));
 
@@ -586,7 +586,7 @@
 
     @Test
     public void testAddNotif_notBubble() {
-        mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
+        mEntryListener.onNotificationAdded(mNonBubbleNotifRow.getEntry());
         mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
 
         verify(mBubbleStateChangeListener, never()).onHasBubblesChanged(anyBoolean());
@@ -631,7 +631,7 @@
 
     @Test
     public void testRemoveBubble_succeeds_appCancel() {
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
@@ -646,7 +646,7 @@
 
     @Test
     public void removeBubble_fails_clearAll()  {
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
@@ -669,7 +669,7 @@
 
     @Test
     public void removeBubble_fails_userDismissNotif() {
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
@@ -692,7 +692,7 @@
 
     @Test
     public void removeBubble_succeeds_userDismissBubble_userDimissNotif() {
-        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mEntryListener.onNotificationAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 4a0c7a3..601d314 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -31,7 +31,6 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.net.LinkProperties;
-import android.net.NetworkCapabilities;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -260,7 +259,9 @@
 
     private final LocalLog mListenLog = new LocalLog(100);
 
-    private PreciseDataConnectionState[] mPreciseDataConnectionState;
+    // Per-phoneMap of APN Type to DataConnectionState
+    private List<Map<String, PreciseDataConnectionState>> mPreciseDataConnectionStates =
+            new ArrayList<Map<String, PreciseDataConnectionState>>();
 
     // Nothing here yet, but putting it here in case we want to add more in the future.
     static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = 0;
@@ -415,7 +416,6 @@
         mCallQuality = copyOf(mCallQuality, mNumPhones);
         mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
         mCallAttributes = copyOf(mCallAttributes, mNumPhones);
-        mPreciseDataConnectionState = copyOf(mPreciseDataConnectionState, mNumPhones);
         mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
         mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
 
@@ -423,6 +423,7 @@
         if (mNumPhones < oldNumPhones) {
             cutListToSize(mCellInfo, mNumPhones);
             cutListToSize(mImsReasonInfo, mNumPhones);
+            cutListToSize(mPreciseDataConnectionStates, mNumPhones);
             return;
         }
 
@@ -454,7 +455,7 @@
             mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-            mPreciseDataConnectionState[i] = new PreciseDataConnectionState();
+            mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
         }
 
         // Note that location can be null for non-phone builds like
@@ -516,7 +517,7 @@
         mCallQuality = new CallQuality[numPhones];
         mCallNetworkType = new int[numPhones];
         mCallAttributes = new CallAttributes[numPhones];
-        mPreciseDataConnectionState = new PreciseDataConnectionState[numPhones];
+        mPreciseDataConnectionStates = new ArrayList<>();
         mCellInfo = new ArrayList<>();
         mImsReasonInfo = new ArrayList<>();
         mEmergencyNumberList = new HashMap<>();
@@ -549,7 +550,7 @@
             mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-            mPreciseDataConnectionState[i] = new PreciseDataConnectionState();
+            mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
         }
 
         // Note that location can be null for non-phone builds like
@@ -922,8 +923,10 @@
                     }
                     if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
                         try {
-                            r.callback.onPreciseDataConnectionStateChanged(
-                                    mPreciseDataConnectionState[phoneId]);
+                            for (PreciseDataConnectionState pdcs
+                                    : mPreciseDataConnectionStates.get(phoneId).values()) {
+                                r.callback.onPreciseDataConnectionStateChanged(pdcs);
+                            }
                         } catch (RemoteException ex) {
                             remove(r.binder);
                         }
@@ -937,7 +940,8 @@
                     }
                     if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) {
                         try {
-                            r.callback.onVoiceActivationStateChanged(mVoiceActivationState[phoneId]);
+                            r.callback.onVoiceActivationStateChanged(
+                                    mVoiceActivationState[phoneId]);
                         } catch (RemoteException ex) {
                             remove(r.binder);
                         }
@@ -1496,20 +1500,38 @@
         }
     }
 
-    public void notifyDataConnectionForSubscriber(int phoneId, int subId, int state,
-                                                  boolean isDataAllowed,
-                                                  String apn, String apnType,
-            LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
-            int networkType, boolean roaming) {
+    /**
+     * Send a notification to registrants that the data connection state has changed.
+     *
+     * @param phoneId the phoneId carrying the data connection
+     * @param subId the subscriptionId for the data connection
+     * @param apnType the APN type that triggered a change in the data connection
+     * @param preciseState a PreciseDataConnectionState that has info about the data connection
+     */
+    public void notifyDataConnectionForSubscriber(
+            int phoneId, int subId, String apnType, PreciseDataConnectionState preciseState) {
         if (!checkNotifyPermission("notifyDataConnection()" )) {
             return;
         }
+
+        String apn = "";
+        int state = TelephonyManager.DATA_UNKNOWN;
+        int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        LinkProperties linkProps = null;
+
+        if (preciseState != null) {
+            apn = preciseState.getDataConnectionApn();
+            state = preciseState.getState();
+            networkType = preciseState.getNetworkType();
+            linkProps = preciseState.getDataConnectionLinkProperties();
+        }
         if (VDBG) {
             log("notifyDataConnectionForSubscriber: subId=" + subId
-                + " state=" + state + " isDataAllowed=" + isDataAllowed
-                + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
-                + " mRecords.size()=" + mRecords.size());
+                    + " state=" + state + "' apn='" + apn
+                    + "' apnType=" + apnType + " networkType=" + networkType
+                    + "' preciseState=" + preciseState);
         }
+
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
                 // We only call the callback when the change is for default APN type.
@@ -1541,30 +1563,48 @@
                     mDataConnectionState[phoneId] = state;
                     mDataConnectionNetworkType[phoneId] = networkType;
                 }
-                mPreciseDataConnectionState[phoneId] = new PreciseDataConnectionState(
-                        state, networkType,
-                        ApnSetting.getApnTypesBitmaskFromString(apnType), apn,
-                        linkProperties, DataFailCause.NONE);
-                for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
-                            && idMatch(r.subId, subId, phoneId)) {
-                        try {
-                            r.callback.onPreciseDataConnectionStateChanged(
-                                    mPreciseDataConnectionState[phoneId]);
-                        } catch (RemoteException ex) {
-                            mRemoveList.add(r.binder);
+
+                boolean needsNotify = false;
+                // State has been cleared for this APN Type
+                if (preciseState == null) {
+                    // We try clear the state and check if the state was previously not cleared
+                    needsNotify = mPreciseDataConnectionStates.get(phoneId).remove(apnType) != null;
+                } else {
+                    // We need to check to see if the state actually changed
+                    PreciseDataConnectionState oldPreciseState =
+                            mPreciseDataConnectionStates.get(phoneId).put(apnType, preciseState);
+                    needsNotify = !preciseState.equals(oldPreciseState);
+                }
+
+                if (needsNotify) {
+                    for (Record r : mRecords) {
+                        if (r.matchPhoneStateListenerEvent(
+                                PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
+                                && idMatch(r.subId, subId, phoneId)) {
+                            try {
+                                r.callback.onPreciseDataConnectionStateChanged(preciseState);
+                            } catch (RemoteException ex) {
+                                mRemoveList.add(r.binder);
+                            }
                         }
                     }
                 }
             }
             handleRemoveListLocked();
         }
-        broadcastDataConnectionStateChanged(state, isDataAllowed, apn, apnType, linkProperties,
-                networkCapabilities, roaming, subId);
+
+        broadcastDataConnectionStateChanged(state, apn, apnType, subId);
     }
 
-    public void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType) {
+    /**
+     * Stub to satisfy the ITelephonyRegistry aidl interface; do not use this function.
+     * @see #notifyDataConnectionFailedForSubscriber
+     */
+    public void notifyDataConnectionFailed(String apnType) {
+        loge("This function should not be invoked");
+    }
+
+    private void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType) {
         if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
             return;
         }
@@ -1574,17 +1614,20 @@
         }
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
-                mPreciseDataConnectionState[phoneId] = new PreciseDataConnectionState(
-                        TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                        ApnSetting.getApnTypesBitmaskFromString(apnType), null, null,
-                        DataFailCause.NONE);
+                mPreciseDataConnectionStates.get(phoneId).put(
+                        apnType,
+                        new PreciseDataConnectionState(
+                                TelephonyManager.DATA_UNKNOWN,
+                                TelephonyManager.NETWORK_TYPE_UNKNOWN,
+                                ApnSetting.getApnTypesBitmaskFromString(apnType), null, null,
+                                DataFailCause.NONE));
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
                             PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onPreciseDataConnectionStateChanged(
-                                    mPreciseDataConnectionState[phoneId]);
+                                    mPreciseDataConnectionStates.get(phoneId).get(apnType));
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
@@ -1772,25 +1815,32 @@
         if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
             return;
         }
+
+        // precise notify invokes imprecise notify
+        notifyDataConnectionFailedForSubscriber(phoneId, subId, apnType);
+
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
-                mPreciseDataConnectionState[phoneId] = new PreciseDataConnectionState(
-                        TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                        ApnSetting.getApnTypesBitmaskFromString(apnType), apn, null, failCause);
+                mPreciseDataConnectionStates.get(phoneId).put(
+                        apnType,
+                        new PreciseDataConnectionState(
+                                TelephonyManager.DATA_UNKNOWN,
+                                TelephonyManager.NETWORK_TYPE_UNKNOWN,
+                                ApnSetting.getApnTypesBitmaskFromString(apnType), null, null,
+                                failCause));
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
                             PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onPreciseDataConnectionStateChanged(
-                                    mPreciseDataConnectionState[phoneId]);
+                                    mPreciseDataConnectionStates.get(phoneId).get(apnType));
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
                     }
                 }
             }
-
             handleRemoveListLocked();
         }
     }
@@ -2048,7 +2098,6 @@
         }
     }
 
-
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -2087,7 +2136,7 @@
                 pw.println("mCallQuality=" + mCallQuality[i]);
                 pw.println("mCallAttributes=" + mCallAttributes[i]);
                 pw.println("mCallNetworkType=" + mCallNetworkType[i]);
-                pw.println("mPreciseDataConnectionState=" + mPreciseDataConnectionState[i]);
+                pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i));
                 pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
                 pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
                 pw.decreaseIndent();
@@ -2247,29 +2296,13 @@
         }
     }
 
-    private void broadcastDataConnectionStateChanged(int state, boolean isDataAllowed, String apn,
-                                                     String apnType, LinkProperties linkProperties,
-                                                     NetworkCapabilities networkCapabilities,
-                                                     boolean roaming, int subId) {
+    private void broadcastDataConnectionStateChanged(int state, String apn,
+                                                     String apnType, int subId) {
         // Note: not reporting to the battery stats service here, because the
         // status bar takes care of that after taking into account all of the
         // required info.
         Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         intent.putExtra(TelephonyManager.EXTRA_STATE, dataStateToString(state));
-        if (!isDataAllowed) {
-            intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
-        }
-        if (linkProperties != null) {
-            intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
-            String iface = linkProperties.getInterfaceName();
-            if (iface != null) {
-                intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
-            }
-        }
-        if (networkCapabilities != null) {
-            intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities);
-        }
-        if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
 
         intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
         intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index e101fe0..5996b7d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4409,7 +4409,6 @@
         return true;
     }
 
-    @Override
     public boolean renameSharedAccountAsUser(Account account, String newName, int userId) {
         userId = handleIncomingUser(userId);
         UserAccounts accounts = getUserAccounts(userId);
@@ -4425,7 +4424,6 @@
         return r > 0;
     }
 
-    @Override
     public boolean removeSharedAccountAsUser(Account account, int userId) {
         return removeSharedAccountAsUser(account, userId, getCallingUid());
     }
@@ -4443,7 +4441,6 @@
         return deleted;
     }
 
-    @Override
     public Account[] getSharedAccountsAsUser(int userId) {
         userId = handleIncomingUser(userId);
         UserAccounts accounts = getUserAccounts(userId);
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 232bc08e..fc67e24 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -77,21 +77,28 @@
     private static final String LOG_TAG = "AttentionManagerService";
     private static final boolean DEBUG = false;
 
-    /** Default value in absence of {@link DeviceConfig} override. */
-    private static final boolean DEFAULT_SERVICE_ENABLED = true;
-
     /** Service will unbind if connection is not used for that amount of time. */
     private static final long CONNECTION_TTL_MILLIS = 60_000;
 
-    /** If the check attention called within that period - cached value will be returned. */
-    private static final long STALE_AFTER_MILLIS = 5_000;
+    /** DeviceConfig flag name, if {@code true}, enables AttentionManagerService features. */
+    private static final String KEY_SERVICE_ENABLED = "service_enabled";
+
+    /** Default value in absence of {@link DeviceConfig} override. */
+    private static final boolean DEFAULT_SERVICE_ENABLED = true;
+
+    /**
+     * DeviceConfig flag name, describes how much time we consider a result fresh; if the check
+     * attention called within that period - cached value will be returned.
+     */
+    @VisibleForTesting static final String KEY_STALE_AFTER_MILLIS = "stale_after_millis";
+
+    /** Default value in absence of {@link DeviceConfig} override. */
+    @VisibleForTesting static final long DEFAULT_STALE_AFTER_MILLIS = 1_000;
 
     /** The size of the buffer that stores recent attention check results. */
     @VisibleForTesting
     protected static final int ATTENTION_CACHE_BUFFER_SIZE = 5;
 
-    /** DeviceConfig flag name, if {@code true}, enables AttentionManagerService features. */
-    private static final String SERVICE_ENABLED = "service_enabled";
     private static String sTestAttentionServicePackage;
     private final Context mContext;
     private final PowerManager mPowerManager;
@@ -160,11 +167,29 @@
 
     @VisibleForTesting
     protected boolean isServiceEnabled() {
-        return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE, SERVICE_ENABLED,
+        return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE, KEY_SERVICE_ENABLED,
                 DEFAULT_SERVICE_ENABLED);
     }
 
     /**
+     * How much time we consider a result fresh; if the check attention called within that period -
+     * cached value will be returned.
+     */
+    @VisibleForTesting
+    protected long getStaleAfterMillis() {
+        final long millis = DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+                KEY_STALE_AFTER_MILLIS,
+                DEFAULT_STALE_AFTER_MILLIS);
+
+        if (millis < 0 || millis > 10_000) {
+            Slog.w(LOG_TAG, "Bad flag value supplied for: " + KEY_STALE_AFTER_MILLIS);
+            return DEFAULT_STALE_AFTER_MILLIS;
+        }
+
+        return millis;
+    }
+
+    /**
      * Checks whether user attention is at the screen and calls in the provided callback.
      *
      * Calling this multiple times quickly in a row will result in either a) returning a cached
@@ -199,7 +224,7 @@
             // throttle frequent requests
             final AttentionCheckCache cache = userState.mAttentionCheckCacheBuffer == null ? null
                     : userState.mAttentionCheckCacheBuffer.getLast();
-            if (cache != null && now < cache.mLastComputed + STALE_AFTER_MILLIS) {
+            if (cache != null && now < cache.mLastComputed + getStaleAfterMillis()) {
                 callbackInternal.onSuccess(cache.mResult, cache.mTimestamp);
                 return true;
             }
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 7098435..a7e40cb 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -59,6 +59,12 @@
             return -1 * Boolean.compare(isLeftHighImportance, isRightHighImportance);
         }
 
+        // If a score has been assigned by notification assistant service, use this service
+        // rank results within each bucket instead of this comparator implementation.
+        if (left.getRankingScore() != right.getRankingScore()) {
+            return -1 * Float.compare(left.getRankingScore(), right.getRankingScore());
+        }
+
         // first all colorized notifications
         boolean leftImportantColorized = isImportantColorized(left);
         boolean rightImportantColorized = isImportantColorized(right);
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index e968fb70..c8afcc9 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -144,6 +144,7 @@
     private int mSystemImportance = IMPORTANCE_UNSPECIFIED;
     private int mAssistantImportance = IMPORTANCE_UNSPECIFIED;
     private int mImportance = IMPORTANCE_UNSPECIFIED;
+    private float mRankingScore = 0f;
     // Field used in global sort key to bypass normal notifications
     private int mCriticality = CriticalNotificationExtractor.NORMAL;
     // A MetricsEvent.NotificationImportanceExplanation, tracking source of mImportance.
@@ -655,6 +656,9 @@
                     importance = Math.min(IMPORTANCE_HIGH, importance);
                     setAssistantImportance(importance);
                 }
+                if (signals.containsKey(Adjustment.KEY_RANKING_SCORE)) {
+                    mRankingScore = signals.getFloat(Adjustment.KEY_RANKING_SCORE);
+                }
                 if (!signals.isEmpty() && adjustment.getIssuer() != null) {
                     mAdjustmentIssuer = adjustment.getIssuer();
                 }
@@ -772,6 +776,10 @@
         return mImportance;
     }
 
+    public float getRankingScore() {
+        return mRankingScore;
+    }
+
     public CharSequence getImportanceExplanation() {
         switch (mImportanceExplanationCode) {
             case MetricsEvent.IMPORTANCE_EXPLANATION_UNKNOWN:
diff --git a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
index a47a567..e90cb46 100644
--- a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
@@ -16,7 +16,11 @@
 
 package com.android.server.attention;
 
+import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
+
 import static com.android.server.attention.AttentionManagerService.ATTENTION_CACHE_BUFFER_SIZE;
+import static com.android.server.attention.AttentionManagerService.DEFAULT_STALE_AFTER_MILLIS;
+import static com.android.server.attention.AttentionManagerService.KEY_STALE_AFTER_MILLIS;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -35,6 +39,7 @@
 import android.os.IPowerManager;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.provider.DeviceConfig;
 import android.service.attention.IAttentionCallback;
 import android.service.attention.IAttentionService;
 
@@ -180,6 +185,45 @@
         assertThat(buffer.get(0)).isEqualTo(cache);
     }
 
+    @Test
+    public void testGetStaleAfterMillis_handlesGoodFlagValue() {
+        DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+                KEY_STALE_AFTER_MILLIS, "123", false);
+        assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(123);
+    }
+
+    @Test
+    public void testGetStaleAfterMillis_handlesBadFlagValue_1() {
+        DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+                KEY_STALE_AFTER_MILLIS, "-123", false);
+        assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(
+                DEFAULT_STALE_AFTER_MILLIS);
+    }
+
+    @Test
+    public void testGetStaleAfterMillis_handlesBadFlagValue_2() {
+        DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+                KEY_STALE_AFTER_MILLIS, "15000", false);
+        assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(
+                DEFAULT_STALE_AFTER_MILLIS);
+    }
+
+    @Test
+    public void testGetStaleAfterMillis_handlesBadFlagValue_3() {
+        DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+                KEY_STALE_AFTER_MILLIS, "abracadabra", false);
+        assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(
+                DEFAULT_STALE_AFTER_MILLIS);
+    }
+
+    @Test
+    public void testGetStaleAfterMillis_handlesBadFlagValue_4() {
+        DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+                KEY_STALE_AFTER_MILLIS, "15_000L", false);
+        assertThat(mSpyAttentionManager.getStaleAfterMillis()).isEqualTo(
+                DEFAULT_STALE_AFTER_MILLIS);
+    }
+
     private class MockIAttentionService implements IAttentionService {
         public void checkAttention(IAttentionCallback callback) throws RemoteException {
             callback.onSuccess(0, 0);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
index 0b4760d..a328568 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.spy;
 
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -271,6 +272,18 @@
     }
 
     @Test
+    public void testRankingScoreOverrides() {
+        NotificationComparator comp = new NotificationComparator(mContext);
+        NotificationRecord recordMinCallNonInterruptive = spy(mRecordMinCallNonInterruptive);
+        assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) < 0);
+
+        when(recordMinCallNonInterruptive.getRankingScore()).thenReturn(1f);
+        assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) > 0);
+        assertTrue(comp.compare(mRecordCheater, recordMinCallNonInterruptive) > 0);
+        assertTrue(comp.compare(mRecordColorizedCall, recordMinCallNonInterruptive) < 0);
+    }
+
+    @Test
     public void testMessaging() {
         NotificationComparator comp = new NotificationComparator(mContext);
         assertTrue(comp.isImportantMessaging(mRecordInlineReply));
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index 257d634..78ad5c5 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -19,8 +19,10 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.net.LinkProperties;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Annotation.ApnType;
@@ -29,6 +31,8 @@
 import android.telephony.Annotation.NetworkType;
 import android.telephony.data.ApnSetting;
 
+import dalvik.system.VMRuntime;
+
 import java.util.Objects;
 
 
@@ -46,35 +50,62 @@
  *   <li>Data connection fail cause.
  * </ul>
  *
- * @hide
  */
-@SystemApi
 public final class PreciseDataConnectionState implements Parcelable {
 
     private @DataState int mState = TelephonyManager.DATA_UNKNOWN;
     private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
     private @DataFailureCause int mFailCause = DataFailCause.NONE;
-    private @ApnType int mAPNTypes = ApnSetting.TYPE_NONE;
-    private String mAPN = "";
+    private @ApnType int mApnTypes = ApnSetting.TYPE_NONE;
+    private String mApn = "";
     private LinkProperties mLinkProperties = null;
+    private ApnSetting mApnSetting = null;
 
     /**
      * Constructor
      *
+     * @deprecated this constructor has been superseded and should not be used.
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
+    @Deprecated
+    @UnsupportedAppUsage // (maxTargetSdk = Build.VERSION_CODES.Q)
+    // FIXME: figure out how to remove the UnsupportedAppUsage and delete this constructor
     public PreciseDataConnectionState(@DataState int state,
                                       @NetworkType int networkType,
-                                      @ApnType int apnTypes, String apn,
-                                      LinkProperties linkProperties,
+                                      @ApnType int apnTypes, @NonNull String apn,
+                                      @Nullable LinkProperties linkProperties,
                                       @DataFailureCause int failCause) {
+        this(state, networkType, apnTypes, apn, linkProperties, failCause, null);
+    }
+
+
+    /**
+     * Constructor
+     *
+     * @param state the state of the data connection
+     * @param networkType the access network that is/would carry this data connection
+     * @param apnTypes the APN types that this data connection carries
+     * @param apnSetting if there is a valid APN for this Data Connection, then the APN Settings;
+     *        if there is no valid APN setting for the specific type, then this will be null
+     * @param linkProperties if the data connection is connected, the properties of the connection
+     * @param failCause in case a procedure related to this data connection fails, a non-zero error
+     *        code indicating the cause of the failure.
+     * @hide
+     */
+    public PreciseDataConnectionState(@DataState int state,
+                                      @NetworkType int networkType,
+                                      @ApnType int apnTypes, @NonNull String apn,
+                                      @Nullable LinkProperties linkProperties,
+                                      @DataFailureCause int failCause,
+                                      @Nullable ApnSetting apnSetting) {
         mState = state;
         mNetworkType = networkType;
-        mAPNTypes = apnTypes;
-        mAPN = apn;
+        mApnTypes = apnTypes;
+        mApn = apn;
         mLinkProperties = linkProperties;
         mFailCause = failCause;
+        mApnSetting = apnSetting;
     }
 
     /**
@@ -93,76 +124,160 @@
     private PreciseDataConnectionState(Parcel in) {
         mState = in.readInt();
         mNetworkType = in.readInt();
-        mAPNTypes = in.readInt();
-        mAPN = in.readString();
-        mLinkProperties = (LinkProperties)in.readParcelable(null);
+        mApnTypes = in.readInt();
+        mApn = in.readString();
+        mLinkProperties = (LinkProperties) in.readParcelable(null);
         mFailCause = in.readInt();
+        mApnSetting = (ApnSetting) in.readParcelable(null);
     }
 
     /**
      * Returns the state of data connection that supported the apn types returned by
      * {@link #getDataConnectionApnTypeBitMask()}
+     *
+     * @deprecated use {@link #getState()}
+     * @hide
      */
+    @Deprecated
+    @SystemApi
     public @DataState int getDataConnectionState() {
+        if (mState == TelephonyManager.DATA_DISCONNECTING
+                && VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) {
+            return TelephonyManager.DATA_CONNECTED;
+        }
+
+        return mState;
+    }
+
+    /**
+     * Returns the high-level state of this data connection.
+     */
+    public @DataState int getState() {
         return mState;
     }
 
     /**
      * Returns the network type associated with this data connection.
+     *
+     * @deprecated use {@link getNetworkType()}
      * @hide
      */
+    @Deprecated
+    @SystemApi
     public @NetworkType int getDataConnectionNetworkType() {
         return mNetworkType;
     }
 
     /**
-     * Returns the data connection APN types supported by this connection and triggers
-     * {@link PreciseDataConnectionState} change.
+     * Returns the network type associated with this data connection.
+     *
+     * Return the current/latest (radio) bearer technology that carries this data connection.
+     * For a variety of reasons, the network type can change during the life of the data
+     * connection, and this information is not reliable unless the physical link is currently
+     * active; (there is currently no mechanism to know whether the physical link is active at
+     * any given moment). Thus, this value is generally correct but may not be relied-upon to
+     * represent the status of the radio bearer at any given moment.
      */
-    public @ApnType int getDataConnectionApnTypeBitMask() {
-        return mAPNTypes;
+    public @NetworkType int getNetworkType() {
+        return mNetworkType;
     }
 
     /**
-     * Returns APN {@link ApnSetting} of this data connection.
+     * Returns the APN types mapped to this data connection.
+     *
+     * @deprecated use {@link #getApnSetting()}
+     * @hide
      */
-    @Nullable
+    @Deprecated
+    @SystemApi
+    public @ApnType int getDataConnectionApnTypeBitMask() {
+        return mApnTypes;
+    }
+
+    /**
+     * Returns APN of this data connection.
+     *
+     * @deprecated use {@link #getApnSetting()}
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @Deprecated
     public String getDataConnectionApn() {
-        return mAPN;
+        return mApn;
     }
 
     /**
      * Get the properties of the network link {@link LinkProperties}.
+     *
+     * @deprecated use {@link #getLinkProperties()}
      * @hide
      */
-    @UnsupportedAppUsage
+    @Deprecated
+    @SystemApi
+    @Nullable
     public LinkProperties getDataConnectionLinkProperties() {
         return mLinkProperties;
     }
 
     /**
-     * Returns data connection fail cause, in case there was a failure.
+     * Get the properties of the network link {@link LinkProperties}.
      */
-    public @Annotation.DataFailureCause int getDataConnectionFailCause() {
+    @Nullable
+    public LinkProperties getLinkProperties() {
+        return mLinkProperties;
+    }
+
+    /**
+     * Returns the cause code generated by the most recent state change.
+     *
+     * @deprecated use {@link #getLastCauseCode()}
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public int getDataConnectionFailCause() {
         return mFailCause;
     }
 
+    /**
+     * Returns the cause code generated by the most recent state change.
+     *
+     * Return the cause code for the most recent change in {@link #getState}. In the event of an
+     * error, this cause code will be non-zero.
+     */
+    // FIXME(b144774287): some of these cause codes should have a prescribed meaning.
+    public int getLastCauseCode() {
+        return mFailCause;
+    }
+
+    /**
+     * Return the APN Settings for this data connection.
+     *
+     * Returns the ApnSetting that was used to configure this data connection.
+     */
+    // FIXME: This shouldn't be nullable; update once the ApnSetting is supplied correctly
+    @Nullable ApnSetting getApnSetting() {
+        return mApnSetting;
+    }
+
     @Override
     public int describeContents() {
         return 0;
     }
 
     @Override
-    public void writeToParcel(Parcel out, int flags) {
+    public void writeToParcel(@NonNull Parcel out, int flags) {
         out.writeInt(mState);
         out.writeInt(mNetworkType);
-        out.writeInt(mAPNTypes);
-        out.writeString(mAPN);
+        out.writeInt(mApnTypes);
+        out.writeString(mApn);
         out.writeParcelable(mLinkProperties, flags);
         out.writeInt(mFailCause);
+        out.writeParcelable(mApnSetting, flags);
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR
+    public static final @NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR
             = new Parcelable.Creator<PreciseDataConnectionState>() {
 
         public PreciseDataConnectionState createFromParcel(Parcel in) {
@@ -176,8 +291,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mState, mNetworkType, mAPNTypes, mAPN, mLinkProperties,
-                mFailCause);
+        return Objects.hash(mState, mNetworkType, mApnTypes, mApn, mLinkProperties,
+                mFailCause, mApnSetting);
     }
 
     @Override
@@ -188,11 +303,12 @@
         }
 
         PreciseDataConnectionState other = (PreciseDataConnectionState) obj;
-        return Objects.equals(mAPN, other.mAPN) && mAPNTypes == other.mAPNTypes
+        return Objects.equals(mApn, other.mApn) && mApnTypes == other.mApnTypes
                 && mFailCause == other.mFailCause
                 && Objects.equals(mLinkProperties, other.mLinkProperties)
                 && mNetworkType == other.mNetworkType
-                && mState == other.mState;
+                && mState == other.mState
+                && Objects.equals(mApnSetting, other.mApnSetting);
     }
 
     @NonNull
@@ -202,10 +318,11 @@
 
         sb.append("Data Connection state: " + mState);
         sb.append(", Network type: " + mNetworkType);
-        sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mAPNTypes));
-        sb.append(", APN: " + mAPN);
+        sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mApnTypes));
+        sb.append(", APN: " + mApn);
         sb.append(", Link properties: " + mLinkProperties);
         sb.append(", Fail cause: " + DataFailCause.toString(mFailCause));
+        sb.append(", Apn Setting: " + mApnSetting);
 
         return sb.toString();
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b1dd2d8..78c5e43 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -801,18 +801,6 @@
     public static final String EXTRA_DATA_APN = PhoneConstants.DATA_APN_KEY;
 
     /**
-     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
-     * for an String representation of the data interface.
-     *
-     * <p class="note">
-     * Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String name)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_DATA_LINK_PROPERTIES_KEY = PhoneConstants.DATA_LINK_PROPERTIES_KEY;
-
-    /**
      * Broadcast intent action for letting the default dialer to know to show voicemail
      * notification.
      *
@@ -5129,6 +5117,7 @@
             DATA_CONNECTING,
             DATA_CONNECTED,
             DATA_SUSPENDED,
+            DATA_DISCONNECTING,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface DataState{}
@@ -5145,6 +5134,12 @@
      * traffic is temporarily unavailable. For example, in a 2G network,
      * data activity may be suspended when a voice call arrives. */
     public static final int DATA_SUSPENDED      = 3;
+    /**
+     * Data connection state: Disconnecting.
+     *
+     * IP traffic may be available but will cease working imminently.
+     */
+    public static final int DATA_DISCONNECTING = 4;
 
     /**
      * Returns a constant indicating the current data connection state
@@ -5154,14 +5149,21 @@
      * @see #DATA_CONNECTING
      * @see #DATA_CONNECTED
      * @see #DATA_SUSPENDED
+     * @see #DATA_DISCONNECTING
      */
     public int getDataState() {
         try {
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return DATA_DISCONNECTED;
-            return telephony.getDataStateForSubId(
+            int state = telephony.getDataStateForSubId(
                     getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
+            if (state == TelephonyManager.DATA_DISCONNECTING
+                    && VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) {
+                return TelephonyManager.DATA_CONNECTED;
+            }
+
+            return state;
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return DATA_DISCONNECTED;
@@ -5182,6 +5184,7 @@
             case DATA_CONNECTING: return "CONNECTING";
             case DATA_CONNECTED: return "CONNECTED";
             case DATA_SUSPENDED: return "SUSPENDED";
+            case DATA_DISCONNECTING: return "DISCONNECTING";
         }
         return "UNKNOWN(" + state + ")";
     }
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstantConversions.java b/telephony/java/com/android/internal/telephony/PhoneConstantConversions.java
index f7f0f29..8640acc 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstantConversions.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstantConversions.java
@@ -16,14 +16,10 @@
 
 package com.android.internal.telephony;
 
-import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
-import android.telephony.PreciseCallState;
 
 import com.android.internal.telephony.PhoneConstants;
 
-import java.util.List;
-
 public class PhoneConstantConversions {
     /**
      * Convert the {@link PhoneConstants.State} enum into the TelephonyManager.CALL_STATE_*
@@ -67,6 +63,8 @@
                 return TelephonyManager.DATA_CONNECTED;
             case SUSPENDED:
                 return TelephonyManager.DATA_SUSPENDED;
+            case DISCONNECTING:
+                return TelephonyManager.DATA_DISCONNECTING;
             default:
                 return TelephonyManager.DATA_DISCONNECTED;
         }
@@ -84,6 +82,8 @@
                 return PhoneConstants.DataState.CONNECTED;
             case TelephonyManager.DATA_SUSPENDED:
                 return PhoneConstants.DataState.SUSPENDED;
+            case TelephonyManager.DATA_DISCONNECTING:
+                return PhoneConstants.DataState.DISCONNECTING;
             default:
                 return PhoneConstants.DataState.DISCONNECTED;
         }
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index fde2c5a..fadb573 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -46,6 +46,7 @@
       * <ul>
       * <li>CONNECTED = IP traffic should be available</li>
       * <li>CONNECTING = Currently setting up data connection</li>
+      * <li>DISCONNECTING = IP temporarily available</li>
       * <li>DISCONNECTED = IP not available</li>
       * <li>SUSPENDED = connection is created but IP traffic is
       *                 temperately not available. i.e. voice call is in place
@@ -55,10 +56,15 @@
     @UnsupportedAppUsage(implicitMember =
             "values()[Lcom/android/internal/telephony/PhoneConstants$DataState;")
     public enum DataState {
-        @UnsupportedAppUsage CONNECTED,
-        @UnsupportedAppUsage CONNECTING,
-        @UnsupportedAppUsage DISCONNECTED,
-        @UnsupportedAppUsage SUSPENDED;
+        @UnsupportedAppUsage
+        CONNECTED,
+        @UnsupportedAppUsage
+        CONNECTING,
+        @UnsupportedAppUsage
+        DISCONNECTED,
+        @UnsupportedAppUsage
+        SUSPENDED,
+        DISCONNECTING;
     };
 
     public static final String STATE_KEY = "state";
@@ -91,20 +97,12 @@
 
     public static final String PHONE_NAME_KEY = "phoneName";
     public static final String DATA_NETWORK_TYPE_KEY = "networkType";
-    public static final String DATA_FAILURE_CAUSE_KEY = "failCause";
     public static final String DATA_APN_TYPE_KEY = "apnType";
     public static final String DATA_APN_KEY = "apn";
-    public static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
-    public static final String DATA_NETWORK_CAPABILITIES_KEY = "networkCapabilities";
 
-    public static final String DATA_IFACE_NAME_KEY = "iface";
-    public static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
-    public static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming";
     public static final String PHONE_IN_ECM_STATE = "phoneinECMState";
     public static final String PHONE_IN_EMERGENCY_CALL = "phoneInEmergencyCall";
 
-    public static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
-
     /**
      * Return codes for supplyPinReturnResult and
      * supplyPukReturnResult APIs