Merge changes from topic "fix-event-dispatch"

* changes:
  Invert BubbleController <-> NEM dependency
  Inline a few methods in NotificationEntryManager
  Change onRemoteEntry() to only fire when entries are removed
diff --git a/api/current.txt b/api/current.txt
index 29d459e..13311d4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -24942,6 +24942,25 @@
     field public static final int TYPE_STRING = 4; // 0x4
   }
 
+  public final class MediaItem2 implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getEndPosition();
+    method public android.media.MediaMetadata getMetadata();
+    method public long getStartPosition();
+    method public void setMetadata(android.media.MediaMetadata);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.MediaItem2> CREATOR;
+    field public static final long POSITION_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL
+  }
+
+  public static class MediaItem2.Builder {
+    ctor public MediaItem2.Builder();
+    method public android.media.MediaItem2 build();
+    method public android.media.MediaItem2.Builder setEndPosition(long);
+    method public android.media.MediaItem2.Builder setMetadata(android.media.MediaMetadata);
+    method public android.media.MediaItem2.Builder setStartPosition(long);
+  }
+
   public final class MediaMetadata implements android.os.Parcelable {
     method public boolean containsKey(java.lang.String);
     method public int describeContents();
@@ -30016,6 +30035,7 @@
     ctor public WifiP2pGroup(android.net.wifi.p2p.WifiP2pGroup);
     method public int describeContents();
     method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList();
+    method public int getFrequency();
     method public java.lang.String getInterface();
     method public java.lang.String getNetworkName();
     method public android.net.wifi.p2p.WifiP2pDevice getOwner();
@@ -37864,7 +37884,11 @@
     method public static java.lang.String getVolumeName(android.net.Uri);
     method public static android.provider.MediaStore.PendingSession openPending(android.content.Context, android.net.Uri);
     method public static android.net.Uri setIncludePending(android.net.Uri);
+    method public static android.net.Uri setIncludeTrashed(android.net.Uri);
     method public static android.net.Uri setRequireOriginal(android.net.Uri);
+    method public static void trash(android.content.Context, android.net.Uri);
+    method public static void trash(android.content.Context, android.net.Uri, long);
+    method public static void untrash(android.content.Context, android.net.Uri);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
     field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
     field public static final java.lang.String ACTION_REVIEW = "android.provider.action.REVIEW";
@@ -38043,6 +38067,7 @@
   }
 
   public static abstract interface MediaStore.DownloadColumns implements android.provider.MediaStore.MediaColumns {
+    field public static final java.lang.String DESCRIPTION = "description";
     field public static final java.lang.String DOWNLOAD_URI = "download_uri";
     field public static final java.lang.String REFERER_URI = "referer_uri";
   }
@@ -38087,6 +38112,7 @@
     field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic";
     field public static final java.lang.String ORIENTATION = "orientation";
     field public static final deprecated java.lang.String PICASA_ID = "picasa_id";
+    field public static final java.lang.String SECONDARY_BUCKET_ID = "secondary_bucket_id";
   }
 
   public static final class MediaStore.Images.Media implements android.provider.MediaStore.Images.ImageColumns {
@@ -38131,11 +38157,13 @@
   public static abstract interface MediaStore.MediaColumns implements android.provider.BaseColumns {
     field public static final deprecated java.lang.String DATA = "_data";
     field public static final java.lang.String DATE_ADDED = "date_added";
+    field public static final java.lang.String DATE_EXPIRES = "date_expires";
     field public static final java.lang.String DATE_MODIFIED = "date_modified";
     field public static final java.lang.String DISPLAY_NAME = "_display_name";
     field public static final java.lang.String HASH = "_hash";
     field public static final java.lang.String HEIGHT = "height";
     field public static final java.lang.String IS_PENDING = "is_pending";
+    field public static final java.lang.String IS_TRASHED = "is_trashed";
     field public static final java.lang.String MIME_TYPE = "mime_type";
     field public static final java.lang.String OWNER_PACKAGE_NAME = "owner_package_name";
     field public static final java.lang.String SIZE = "_size";
@@ -38211,6 +38239,7 @@
     field public static final deprecated java.lang.String LONGITUDE = "longitude";
     field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic";
     field public static final java.lang.String RESOLUTION = "resolution";
+    field public static final java.lang.String SECONDARY_BUCKET_ID = "secondary_bucket_id";
     field public static final java.lang.String TAGS = "tags";
   }
 
diff --git a/api/system-current.txt b/api/system-current.txt
index 05aa0ad..e79ede8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4588,6 +4588,7 @@
     method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException;
     method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException;
     method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException;
+    method public static boolean hasIsolatedStorage();
     field public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
   }
 
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 7a993fd..041fbfa 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -2837,8 +2837,6 @@
 Lcom/android/internal/telephony/dataconnection/DcTracker;->mResolver:Landroid/content/ContentResolver;
 Lcom/android/internal/telephony/dataconnection/DcTracker;->mState:Lcom/android/internal/telephony/DctConstants$State;
 Lcom/android/internal/telephony/dataconnection/DcTracker;->mSubscriptionManager:Landroid/telephony/SubscriptionManager;
-Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyDataConnection(Ljava/lang/String;)V
-Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyOffApnsOfAvailability(Ljava/lang/String;)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentDataStallAlarm(Landroid/content/Intent;)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentProvisioningApnAlarm(Landroid/content/Intent;)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onRecordsLoadedOrSubIdChanged()V
@@ -3290,7 +3288,7 @@
 Lcom/android/internal/telephony/ITelephonyRegistry;->listen(Ljava/lang/String;Lcom/android/internal/telephony/IPhoneStateListener;IZ)V
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellInfo(Ljava/util/List;)V
-Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;)V
 Lcom/android/internal/telephony/IWapPushManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IWapPushManager;
 Lcom/android/internal/telephony/IWapPushManager;->addPackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z
 Lcom/android/internal/telephony/IWapPushManager;->deletePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
diff --git a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java
index 9bebbd2..d382eb9 100644
--- a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java
+++ b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java
@@ -17,6 +17,7 @@
 
 import android.annotation.Nullable;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.RemoteException;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -52,7 +53,7 @@
     @VisibleForTesting(visibility = Visibility.PACKAGE)
     public HdmiAudioSystemClient(IHdmiControlService service, @Nullable Handler handler) {
         super(service);
-        mHandler = handler == null ? new Handler() : handler;
+        mHandler = handler == null ? new Handler(Looper.getMainLooper()) : handler;
     }
 
     /** @hide */
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 72a6ffe..b520d2c 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -388,6 +388,19 @@
     }
 
     /**
+     * Gets whether the system is in system audio mode.
+     *
+     * @hide
+     */
+    public boolean getSystemAudioMode() {
+        try {
+            return mService.getSystemAudioMode();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Listener used to get hotplug event from HDMI port.
      */
     public interface HotplugEventListener {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 9594a71..735f4f2 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1540,6 +1540,7 @@
     }
 
     /** {@hide} */
+    @SystemApi
     @TestApi
     public static boolean hasIsolatedStorage() {
         // Prefer to use snapshot for current boot when available
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index e5fd29c..b348da4 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -409,6 +409,15 @@
         public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
 
         /**
+         * Similar to {@link #COLUMN_MEDIAPROVIDER_URI}, except this cannot be updated/queried
+         * by apps and will be the source of truth when updating/deleting download entries in
+         * MediaProvider database.
+         *
+         * <P>Type: TEXT</P>
+         */
+        public static final String COLUMN_MEDIASTORE_URI = "mediastore_uri";
+
+        /**
          * The column that is used to remember whether the media scanner was invoked.
          * It can take the values: null or 0(not scanned), 1(scanned), 2 (not scannable).
          * <P>Type: TEXT</P>
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index c4e2b12..cdbc979 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -17,6 +17,7 @@
 package android.provider;
 
 import android.annotation.BytesLong;
+import android.annotation.DurationMillisLong;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -55,6 +56,7 @@
 import android.os.storage.VolumeInfo;
 import android.service.media.CameraPrewarmService;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -131,6 +133,8 @@
     /** {@hide} */
     public static final String PARAM_INCLUDE_PENDING = "includePending";
     /** {@hide} */
+    public static final String PARAM_INCLUDE_TRASHED = "includeTrashed";
+    /** {@hide} */
     public static final String PARAM_PROGRESS = "progress";
     /** {@hide} */
     public static final String PARAM_REQUIRE_ORIGINAL = "requireOriginal";
@@ -485,12 +489,29 @@
      * By default no pending items are returned.
      *
      * @see MediaColumns#IS_PENDING
+     * @see MediaStore#setIncludePending(Uri)
+     * @see MediaStore#createPending(Context, PendingParams)
      */
     public static @NonNull Uri setIncludePending(@NonNull Uri uri) {
         return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_PENDING, "1").build();
     }
 
     /**
+     * Update the given {@link Uri} to also include any trashed media items from
+     * calls such as
+     * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
+     * By default no trashed items are returned.
+     *
+     * @see MediaColumns#IS_TRASHED
+     * @see MediaStore#setIncludeTrashed(Uri)
+     * @see MediaStore#trash(Context, Uri)
+     * @see MediaStore#untrash(Context, Uri)
+     */
+    public static @NonNull Uri setIncludeTrashed(@NonNull Uri uri) {
+        return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_TRASHED, "1").build();
+    }
+
+    /**
      * Update the given {@link Uri} to indicate that the caller requires the
      * original file contents when calling
      * {@link ContentResolver#openFileDescriptor(Uri, String)}.
@@ -516,6 +537,9 @@
      *
      * @return token which can be passed to {@link #openPending(Context, Uri)}
      *         to work with this pending item.
+     * @see MediaColumns#IS_PENDING
+     * @see MediaStore#setIncludePending(Uri)
+     * @see MediaStore#createPending(Context, PendingParams)
      */
     public static @NonNull Uri createPending(@NonNull Context context,
             @NonNull PendingParams params) {
@@ -572,6 +596,8 @@
             this.insertValues.put(MediaColumns.DATE_ADDED, now);
             this.insertValues.put(MediaColumns.DATE_MODIFIED, now);
             this.insertValues.put(MediaColumns.IS_PENDING, 1);
+            this.insertValues.put(MediaColumns.DATE_EXPIRES,
+                    (System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS) / 1000);
         }
 
         /**
@@ -696,6 +722,7 @@
         public @NonNull Uri publish() {
             final ContentValues values = new ContentValues();
             values.put(MediaColumns.IS_PENDING, 0);
+            values.putNull(MediaColumns.DATE_EXPIRES);
             mContext.getContentResolver().update(mUri, values, null, null);
             return mUri;
         }
@@ -717,6 +744,67 @@
     }
 
     /**
+     * Mark the given item as being "trashed", meaning it should be deleted at
+     * some point in the future. This is a more gentle operation than simply
+     * calling {@link ContentResolver#delete(Uri, String, String[])}, which
+     * would take effect immediately.
+     * <p>
+     * This method preserves trashed items for at least 48 hours before erasing
+     * them, giving the user a chance to untrash the item.
+     *
+     * @see MediaColumns#IS_TRASHED
+     * @see MediaStore#setIncludeTrashed(Uri)
+     * @see MediaStore#trash(Context, Uri)
+     * @see MediaStore#untrash(Context, Uri)
+     */
+    public static void trash(@NonNull Context context, @NonNull Uri uri) {
+        trash(context, uri, 48 * DateUtils.HOUR_IN_MILLIS);
+    }
+
+    /**
+     * Mark the given item as being "trashed", meaning it should be deleted at
+     * some point in the future. This is a more gentle operation than simply
+     * calling {@link ContentResolver#delete(Uri, String, String[])}, which
+     * would take effect immediately.
+     * <p>
+     * This method preserves trashed items for at least the given timeout before
+     * erasing them, giving the user a chance to untrash the item.
+     *
+     * @see MediaColumns#IS_TRASHED
+     * @see MediaStore#setIncludeTrashed(Uri)
+     * @see MediaStore#trash(Context, Uri)
+     * @see MediaStore#untrash(Context, Uri)
+     */
+    public static void trash(@NonNull Context context, @NonNull Uri uri,
+            @DurationMillisLong long timeoutMillis) {
+        if (timeoutMillis < 0) {
+            throw new IllegalArgumentException();
+        }
+
+        final ContentValues values = new ContentValues();
+        values.put(MediaColumns.IS_TRASHED, 1);
+        values.put(MediaColumns.DATE_EXPIRES,
+                (System.currentTimeMillis() + timeoutMillis) / 1000);
+        context.getContentResolver().update(uri, values, null, null);
+    }
+
+    /**
+     * Mark the given item as being "untrashed", meaning it should no longer be
+     * deleted as previously requested through {@link #trash(Context, Uri)}.
+     *
+     * @see MediaColumns#IS_TRASHED
+     * @see MediaStore#setIncludeTrashed(Uri)
+     * @see MediaStore#trash(Context, Uri)
+     * @see MediaStore#untrash(Context, Uri)
+     */
+    public static void untrash(@NonNull Context context, @NonNull Uri uri) {
+        final ContentValues values = new ContentValues();
+        values.put(MediaColumns.IS_TRASHED, 0);
+        values.putNull(MediaColumns.DATE_EXPIRES);
+        context.getContentResolver().update(uri, values, null, null);
+    }
+
+    /**
      * Common fields for most MediaProvider tables
      */
     public interface MediaColumns extends BaseColumns {
@@ -821,12 +909,34 @@
          * <p>
          * Type: BOOLEAN
          *
+         * @see MediaColumns#IS_PENDING
+         * @see MediaStore#setIncludePending(Uri)
          * @see MediaStore#createPending(Context, PendingParams)
-         * @see MediaStore#PARAM_INCLUDE_PENDING
          */
         public static final String IS_PENDING = "is_pending";
 
         /**
+         * Flag indicating if a media item is trashed.
+         * <p>
+         * Type: BOOLEAN
+         *
+         * @see MediaColumns#IS_TRASHED
+         * @see MediaStore#setIncludeTrashed(Uri)
+         * @see MediaStore#trash(Context, Uri)
+         * @see MediaStore#untrash(Context, Uri)
+         */
+        public static final String IS_TRASHED = "is_trashed";
+
+        /**
+         * The time the file should be considered expired. Units are seconds
+         * since 1970. Typically only meaningful in the context of
+         * {@link #IS_PENDING} or {@link #IS_TRASHED}.
+         * <p>
+         * Type: INTEGER
+         */
+        public static final String DATE_EXPIRES = "date_expires";
+
+        /**
          * The width of the image/video in pixels.
          */
         public static final String WIDTH = "width";
@@ -915,6 +1025,11 @@
             return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("dir").build();
         }
 
+        /** @hide */
+        public static final Uri getContentUriForPath(String path) {
+            return getContentUri(getVolumeNameForPath(path));
+        }
+
         /**
          * Fields for master table for all media files.
          * Table also contains MediaColumns._ID, DATA, SIZE and DATE_MODIFIED.
@@ -1021,6 +1136,13 @@
          * Type: TEXT
          */
         String REFERER_URI = "referer_uri";
+
+        /**
+         * The description of the download.
+         * <p>
+         * Type: Text
+         */
+        String DESCRIPTION = "description";
     }
 
     /**
@@ -1251,18 +1373,32 @@
             public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
 
             /**
-             * The bucket id of the image. This is a read-only property that
-             * is automatically computed from the DATA column.
-             * <P>Type: TEXT</P>
+             * The primary bucket ID of this media item. This can be useful to
+             * present the user a first-level clustering of related media items.
+             * This is a read-only column that is automatically computed.
+             * <p>
+             * Type: INTEGER
              */
             public static final String BUCKET_ID = "bucket_id";
 
             /**
-             * The bucket display name of the image. This is a read-only property that
-             * is automatically computed from the DATA column.
-             * <P>Type: TEXT</P>
+             * The primary bucket display name of this media item. This can be
+             * useful to present the user a first-level clustering of related
+             * media items. This is a read-only column that is automatically
+             * computed.
+             * <p>
+             * Type: TEXT
              */
             public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+
+            /**
+             * The secondary bucket ID of this media item. This can be useful to
+             * present the user a second-level clustering of related media
+             * items. This is a read-only column that is automatically computed.
+             * <p>
+             * Type: INTEGER
+             */
+            public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id";
         }
 
         public static final class Media implements ImageColumns {
@@ -2500,20 +2636,34 @@
             public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
 
             /**
-             * The bucket id of the video. This is a read-only property that
-             * is automatically computed from the DATA column.
-             * <P>Type: TEXT</P>
+             * The primary bucket ID of this media item. This can be useful to
+             * present the user a first-level clustering of related media items.
+             * This is a read-only column that is automatically computed.
+             * <p>
+             * Type: INTEGER
              */
             public static final String BUCKET_ID = "bucket_id";
 
             /**
-             * The bucket display name of the video. This is a read-only property that
-             * is automatically computed from the DATA column.
-             * <P>Type: TEXT</P>
+             * The primary bucket display name of this media item. This can be
+             * useful to present the user a first-level clustering of related
+             * media items. This is a read-only column that is automatically
+             * computed.
+             * <p>
+             * Type: TEXT
              */
             public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
 
             /**
+             * The secondary bucket ID of this media item. This can be useful to
+             * present the user a second-level clustering of related media
+             * items. This is a read-only column that is automatically computed.
+             * <p>
+             * Type: INTEGER
+             */
+            public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id";
+
+            /**
              * The bookmark for the video. Time in ms. Represents the location in the video that the
              * video should start playing at the next time it is opened. If the value is null or
              * out of the range 0..DURATION-1 then the video should start playing from the
diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java
index 9f7560c..54cfc00 100644
--- a/core/java/android/view/AccessibilityIterators.java
+++ b/core/java/android/view/AccessibilityIterators.java
@@ -147,6 +147,9 @@
         @Override
         public void onConfigurationChanged(Configuration globalConfig) {
             final Locale locale = globalConfig.getLocales().get(0);
+            if (locale == null) {
+                return;
+            }
             if (!mLocale.equals(locale)) {
                 mLocale = locale;
                 onLocaleChanged(locale);
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index be81c06..ffd4156 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -784,24 +784,8 @@
             ta.recycle();
         }
 
-        if (name.equals(TAG_1995)) {
-            // Let's party like it's 1995!
-            return new BlinkLayout(context, attrs);
-        }
-
         try {
-            View view;
-            if (mFactory2 != null) {
-                view = mFactory2.onCreateView(parent, name, context, attrs);
-            } else if (mFactory != null) {
-                view = mFactory.onCreateView(name, context, attrs);
-            } else {
-                view = null;
-            }
-
-            if (view == null && mPrivateFactory != null) {
-                view = mPrivateFactory.onCreateView(parent, name, context, attrs);
-            }
+            View view = tryCreateView(parent, name, context, attrs);
 
             if (view == null) {
                 final Object lastContext = mConstructorArgs[0];
@@ -836,6 +820,48 @@
     }
 
     /**
+     * Tries to create a view from a tag name using the supplied attribute set.
+     *
+     * This method gives the factory provided by {@link LayoutInflater#setFactory} and
+     * {@link LayoutInflater#setFactory2} a chance to create a view. However, it does not apply all
+     * of the general view creation logic, and thus may return {@code null} for some tags. This
+     * method is used by {@link LayoutInflater#inflate} in creating {@code View} objects.
+     *
+     * @hide for use by precompiled layouts.
+     *
+     * @param parent the parent view, used to inflate layout params
+     * @param name the name of the XML tag used to define the view
+     * @param context the inflation context for the view, typically the
+     *                {@code parent} or base layout inflater context
+     * @param attrs the attribute set for the XML tag used to define the view
+     */
+    @UnsupportedAppUsage(trackingBug = 122360734)
+    @Nullable
+    public final View tryCreateView(@Nullable View parent, @NonNull String name,
+        @NonNull Context context,
+        @NonNull AttributeSet attrs) {
+        if (name.equals(TAG_1995)) {
+            // Let's party like it's 1995!
+            return new BlinkLayout(context, attrs);
+        }
+
+        View view;
+        if (mFactory2 != null) {
+            view = mFactory2.onCreateView(parent, name, context, attrs);
+        } else if (mFactory != null) {
+            view = mFactory.onCreateView(name, context, attrs);
+        } else {
+            view = null;
+        }
+
+        if (view == null && mPrivateFactory != null) {
+            view = mPrivateFactory.onCreateView(parent, name, context, attrs);
+        }
+
+        return view;
+    }
+
+    /**
      * Recursive method used to inflate internal (non-root) children. This
      * method calls through to {@link #rInflate} using the parent context as
      * the inflation context.
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index dc660a4..a319d83 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -30,6 +30,14 @@
     public static final String CONTROL_PRIVAPP_PERMISSIONS =
             SystemProperties.get("ro.control_privapp_permissions");
 
+    /**
+     * Property to indicate if a CEC audio device should forward volume keys when system audio
+     * mode is off.
+     */
+    public static final boolean CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF =
+            SystemProperties.getBoolean(
+                    "ro.hdmi.cec_audio_device_forward_volume_keys_system_audio_mode_off", false);
+
     // ------ ro.config.* -------- //
     public static final boolean CONFIG_AVOID_GFX_ACCEL =
             SystemProperties.getBoolean("ro.config.avoid_gfx_accel", false);
diff --git a/core/res/res/values-land/dimens_permission_controller.xml b/core/res/res/values-land/dimens_permission_controller.xml
deleted file mode 100644
index 2146241..0000000
--- a/core/res/res/values-land/dimens_permission_controller.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<!-- Landscape dimensions for the permission grant dialog. -->
-<resources>
-    <!-- Assuming the dimension of a sailfish, this yields 95% width in splitscreen and 65% in
-         landscape -->
-    <dimen name="permissionGrantDialogWeight">8.6</dimen>
-    <dimen name="permissionGrantDialogWidth">334dp</dimen>
-</resources>
diff --git a/core/res/res/values-night/themes_permission_controller.xml b/core/res/res/values-night/themes_permission_controller.xml
deleted file mode 100644
index a071927..0000000
--- a/core/res/res/values-night/themes_permission_controller.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<!-- themes for the permission grant dialog. -->
-<resources>
-    <style name="Theme.DeviceDefault.PermissionGrantApp"
-           parent="@style/Theme.DeviceDefault.Panel">
-        <item name="windowIsFloating">false</item>
-        <item name="windowTranslucentStatus">true</item>
-        <item name="backgroundDimEnabled">true</item>
-        <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
-    </style>
-
-    <style name="Theme.DeviceDefault.PermissionGrant"
-           parent="@style/Theme.DeviceDefault.Dialog">
-        <item name="titleTextStyle">@style/PermissionGrantTitleMessage</item>
-    </style>
-</resources>
diff --git a/core/res/res/values-port/dimens_permission_controller.xml b/core/res/res/values-port/dimens_permission_controller.xml
deleted file mode 100644
index af28713..0000000
--- a/core/res/res/values-port/dimens_permission_controller.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<!-- portrait dimensions for the permission grant dialog. -->
-<resources>
-    <!-- This yields 95% width -->
-    <dimen name="permissionGrantDialogWeight">380</dimen>
-    <dimen name="permissionGrantDialogWidth">0dp</dimen>
-</resources>
diff --git a/core/res/res/values/styles_permission_controller.xml b/core/res/res/values/styles_permission_controller.xml
deleted file mode 100644
index 5a9d3e6..0000000
--- a/core/res/res/values/styles_permission_controller.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<resources>
-    <!-- styles for the permission grant dialog. -->
-    <style name="PermissionGrantDialog">
-        <item name="background">?attr/windowBackground</item>
-        <item name="elevation">?attr/windowElevation</item>
-        <item name="layout_weight">@dimen/permissionGrantDialogWeight</item>
-        <item name="layout_width">@dimen/permissionGrantDialogWidth</item>
-    </style>
-
-    <style name="PermissionGrantTitleIcon">
-        <item name="layout_width">24dp</item>
-        <item name="layout_height">24dp</item>
-        <item name="layout_marginBottom">12dp</item>
-        <item name="tint">?attr/colorAccent</item>
-        <item name="scaleType">fitCenter</item>
-    </style>
-
-    <style name="PermissionGrantTitleMessage"
-           parent="@style/TextAppearance.DeviceDefault">
-        <item name="gravity">center</item>
-        <item name="textSize">20sp</item>
-        <item name="textColor">?attr/textColorPrimary</item>
-    </style>
-
-    <style name="PermissionGrantIndex"
-           parent="@style/TextAppearance.DeviceDefault">
-        <item name="paddingEnd">12dp</item>
-        <item name="singleLine">true</item>
-        <item name="textColor">?attr/textColorSecondary</item>
-    </style>
-
-    <style name="PermissionGrantDescription">
-        <item name="layout_marginStart">24dp</item>
-        <item name="layout_marginEnd">24dp</item>
-    </style>
-
-    <style name="PermissionGrantContent">
-        <item name="layout_marginStart">24dp</item>
-        <item name="layout_marginEnd">24dp</item>
-    </style>
-
-    <style name="PermissionGrantDetailMessage"
-           parent="@style/TextAppearance.DeviceDefault">
-        <item name="layout_marginTop">18dp</item>
-        <item name="textColor">?attr/textColorPrimary</item>
-        <item name="textSize">16sp</item>
-    </style>
-
-    <!-- styles for the permission review screen. -->
-    <style name="PermissionReviewDescription">
-        <item name="layout_marginTop">20dp</item>
-        <item name="layout_marginStart">24dp</item>
-        <item name="layout_marginBottom">16dp</item>
-        <item name="layout_marginEnd">24dp</item>
-    </style>
-
-    <style name="PermissionReviewTitleIcon">
-        <item name="layout_marginTop">4dp</item>
-        <item name="layout_width">36dp</item>
-        <item name="layout_height">36dp</item>
-        <item name="scaleType">fitCenter</item>
-    </style>
-
-    <style name="PermissionReviewTitleMessage"
-           parent="@style/TextAppearance.DeviceDefault">
-        <item name="paddingStart">22dp</item>
-        <item name="textSize">20sp</item>
-        <item name="textColor">?attr/textColorPrimary</item>
-    </style>
-
-    <style name="PermissionReviewSettings">
-        <item name="layout_marginStart">8dp</item>
-        <item name="layout_marginEnd">8dp</item>
-    </style>
-
-    <style name="PermissionReviewButtonBar">
-        <item name="layout_marginStart">24dp</item>
-        <item name="layout_marginEnd">16dp</item>
-        <item name="layout_marginBottom">4dp</item>
-    </style>
-</resources>
diff --git a/core/res/res/values/themes_permission_controller.xml b/core/res/res/values/themes_permission_controller.xml
deleted file mode 100644
index 205c4eb..0000000
--- a/core/res/res/values/themes_permission_controller.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2018 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<resources>
-    <!-- themes for the permission grant dialog. -->
-    <style name="Theme.DeviceDefault.PermissionGrantApp"
-           parent="@style/Theme.DeviceDefault.Light.Panel">
-        <item name="windowIsFloating">false</item>
-        <item name="windowTranslucentStatus">true</item>
-        <item name="backgroundDimEnabled">true</item>
-        <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
-    </style>
-
-    <style name="Theme.DeviceDefault.PermissionGrant"
-           parent="@style/Theme.DeviceDefault.Light.Dialog">
-        <item name="titleTextStyle">@style/PermissionGrantTitleMessage</item>
-    </style>
-
-    <!-- themes for the permission review dialog. -->
-    <style name="Theme.DeviceDefault.PermissionReviewApp"
-           parent="@style/Theme.DeviceDefault.Settings">
-        <item name="windowActionBar">false</item>
-        <item name="windowNoTitle">true</item>
-        <item name="titleTextStyle">@style/PermissionReviewTitleMessage</item>
-    </style>
-</resources>
diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java
index 235325e..c496cf7 100644
--- a/media/java/android/media/MediaItem2.java
+++ b/media/java/android/media/MediaItem2.java
@@ -40,9 +40,8 @@
  * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
  * for consistent behavior across all devices.
  * <p>
- * @hide
  */
-public class MediaItem2 implements Parcelable {
+public final class MediaItem2 implements Parcelable {
     private static final String TAG = "MediaItem2";
 
     // intentionally less than long.MAX_VALUE.
@@ -69,7 +68,6 @@
                 }
             };
 
-    // TODO: Use SessionPlayer2.UNKNOWN_TIME instead
     private static final long UNKNOWN_TIME = -1;
 
     private final long mStartPositionMs;
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 0057875..fb18c3b 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -25,8 +25,10 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
+import android.graphics.SurfaceTexture;
+import android.media.SubtitleController.Anchor;
+import android.media.SubtitleTrack.RenderingWidget;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -35,30 +37,19 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
-import android.os.Process;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
-import android.util.ArrayMap;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.widget.VideoView;
-import android.graphics.SurfaceTexture;
-import android.media.AudioManager;
-import android.media.MediaDrm;
-import android.media.MediaFormat;
-import android.media.MediaTimeProvider;
-import android.media.PlaybackParams;
-import android.media.SubtitleController;
-import android.media.SubtitleController.Anchor;
-import android.media.SubtitleData;
-import android.media.SubtitleTrack.RenderingWidget;
-import android.media.SyncParams;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
@@ -72,7 +63,6 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.Runnable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
@@ -2105,9 +2095,11 @@
         mOnInfoListener = null;
         mOnVideoSizeChangedListener = null;
         mOnTimedTextListener = null;
-        if (mTimeProvider != null) {
-            mTimeProvider.close();
-            mTimeProvider = null;
+        synchronized (mTimeProviderLock) {
+            if (mTimeProvider != null) {
+                mTimeProvider.close();
+                mTimeProvider = null;
+            }
         }
         synchronized(this) {
             mSubtitleDataListenerDisabled = false;
@@ -2147,9 +2139,11 @@
         if (mSubtitleController != null) {
             mSubtitleController.reset();
         }
-        if (mTimeProvider != null) {
-            mTimeProvider.close();
-            mTimeProvider = null;
+        synchronized (mTimeProviderLock) {
+            if (mTimeProvider != null) {
+                mTimeProvider.close();
+                mTimeProvider = null;
+            }
         }
 
         stayAwake(false);
@@ -2790,12 +2784,17 @@
                 synchronized (mIndexTrackPairs) {
                     mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
                 }
-                Handler h = mTimeProvider.mEventHandler;
-                int what = TimeProvider.NOTIFY;
-                int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
-                Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, contents.getBytes());
-                Message m = h.obtainMessage(what, arg1, 0, trackData);
-                h.sendMessage(m);
+                synchronized (mTimeProviderLock) {
+                    if (mTimeProvider != null) {
+                        Handler h = mTimeProvider.mEventHandler;
+                        int what = TimeProvider.NOTIFY;
+                        int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+                        Pair<SubtitleTrack, byte[]> trackData =
+                                Pair.create(track, contents.getBytes());
+                        Message m = h.obtainMessage(what, arg1, 0, trackData);
+                        h.sendMessage(m);
+                    }
+                }
                 return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
             }
 
@@ -3020,12 +3019,17 @@
                             total += bytes;
                         }
                     }
-                    Handler h = mTimeProvider.mEventHandler;
-                    int what = TimeProvider.NOTIFY;
-                    int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
-                    Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, bos.toByteArray());
-                    Message m = h.obtainMessage(what, arg1, 0, trackData);
-                    h.sendMessage(m);
+                    synchronized (mTimeProviderLock) {
+                        if (mTimeProvider != null) {
+                            Handler h = mTimeProvider.mEventHandler;
+                            int what = TimeProvider.NOTIFY;
+                            int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+                            Pair<SubtitleTrack, byte[]> trackData =
+                                    Pair.create(track, bos.toByteArray());
+                            Message m = h.obtainMessage(what, arg1, 0, trackData);
+                            h.sendMessage(m);
+                        }
+                    }
                     return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
                 } catch (Exception e) {
                     Log.e(TAG, e.getMessage(), e);
@@ -3308,14 +3312,17 @@
     private static final int MEDIA_AUDIO_ROUTING_CHANGED = 10000;
 
     private TimeProvider mTimeProvider;
+    private final Object mTimeProviderLock = new Object();
 
     /** @hide */
     @UnsupportedAppUsage
     public MediaTimeProvider getMediaTimeProvider() {
-        if (mTimeProvider == null) {
-            mTimeProvider = new TimeProvider(this);
+        synchronized (mTimeProviderLock) {
+            if (mTimeProvider == null) {
+                mTimeProvider = new TimeProvider(this);
+            }
+            return mTimeProvider;
         }
-        return mTimeProvider;
     }
 
     private class EventHandler extends Handler
diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java
index 4712cdd..1ee851f 100644
--- a/media/java/android/media/MediaSession2.java
+++ b/media/java/android/media/MediaSession2.java
@@ -464,7 +464,21 @@
             if (mId == null) {
                 mId = "";
             }
-            return new MediaSession2(mContext, mId, mSessionActivity, mCallbackExecutor, mCallback);
+            MediaSession2 session2 = new MediaSession2(mContext, mId, mSessionActivity,
+                    mCallbackExecutor, mCallback);
+
+            // Notify framework about the newly create session after the constructor is finished.
+            // Otherwise, framework may access the session before the initialization is finished.
+            try {
+                MediaSessionManager manager = (MediaSessionManager) mContext.getSystemService(
+                        Context.MEDIA_SESSION_SERVICE);
+                manager.notifySession2Created(session2.getSessionToken());
+            } catch (Exception e) {
+                session2.close();
+                throw e;
+            }
+
+            return session2;
         }
     }
 
diff --git a/media/java/android/media/Session2Token.aidl b/media/java/android/media/Session2Token.aidl
new file mode 100644
index 0000000..c5980e9
--- /dev/null
+++ b/media/java/android/media/Session2Token.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+parcelable Session2Token;
diff --git a/media/java/android/media/Session2Token.java b/media/java/android/media/Session2Token.java
index 7642faa..4634c69 100644
--- a/media/java/android/media/Session2Token.java
+++ b/media/java/android/media/Session2Token.java
@@ -102,7 +102,8 @@
     private final ComponentName mComponentName;
 
     /**
-     * Constructor for the token.
+     * Constructor for the token with type {@link #TYPE_SESSION_SERVICE} or
+     * {@link #TYPE_LIBRARY_SERVICE}.
      *
      * @param context The context.
      * @param serviceComponent The component name of the service.
@@ -119,7 +120,7 @@
         final int uid = getUid(manager, serviceComponent.getPackageName());
 
         // TODO: Uncomment below to stop hardcode type.
-        final int type = TYPE_SESSION;
+        final int type = TYPE_SESSION_SERVICE;
 //        final int type;
 //        if (isInterfaceDeclared(manager, MediaLibraryService2.SERVICE_INTERFACE,
 //                serviceComponent)) {
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index d6c226f..51148e2 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -17,6 +17,7 @@
 
 import android.content.ComponentName;
 import android.media.IRemoteVolumeController;
+import android.media.Session2Token;
 import android.media.session.IActiveSessionsListener;
 import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
@@ -32,6 +33,7 @@
  */
 interface ISessionManager {
     ISession createSession(String packageName, in ISessionCallback cb, String tag, int userId);
+    void notifySession2Created(in Session2Token sessionToken);
     List<IBinder> getSessions(in ComponentName compName, int userId);
     void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
             boolean needWakeLock);
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 4221d66..ef5cf00 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -26,6 +26,8 @@
 import android.content.Context;
 import android.media.AudioManager;
 import android.media.IRemoteVolumeController;
+import android.media.MediaSession2;
+import android.media.Session2Token;
 import android.media.browse.MediaBrowser;
 import android.os.Handler;
 import android.os.IBinder;
@@ -102,6 +104,30 @@
     }
 
     /**
+     * Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is
+     * created.
+     * <p>
+     * Do not use this API directly, but create a new instance through the
+     * {@link MediaSession2.Builder} instead.
+     *
+     * @param token newly created session2 token
+     * @hide
+     */
+    public void notifySession2Created(@NonNull Session2Token token) {
+        if (token == null) {
+            throw new IllegalArgumentException("token shouldn't be null");
+        }
+        if (token.getType() != Session2Token.TYPE_SESSION) {
+            throw new IllegalArgumentException("token's type should be TYPE_SESSION");
+        }
+        try {
+            mService.notifySession2Created(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Get a list of controllers for all ongoing sessions. The controllers will
      * be provided in priority order with the most important controller at index
      * 0.
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 58feef5..24d7011 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -35,7 +35,6 @@
 
 public class A2dpProfile implements LocalBluetoothProfile {
     private static final String TAG = "A2dpProfile";
-    private static boolean V = false;
 
     private Context mContext;
 
@@ -60,7 +59,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothA2dp) proxy;
             // We just bound to the service, so refresh the UI for any connected A2DP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -79,7 +77,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
@@ -302,7 +299,7 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.A2DP,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index 988062d..873dd1a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -55,7 +55,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "Bluetooth service connected");
             mService = (BluetoothA2dpSink) proxy;
             // We just bound to the service, so refresh the UI for any connected A2DP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -74,7 +73,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index 62507f5..6b6df9b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -58,7 +58,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothHeadset) proxy;
             // We just bound to the service, so refresh the UI for any connected HFP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -80,7 +79,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG,"Bluetooth service disconnected");
             mProfileManager.callServiceDisconnectedListeners();
             mIsProfileReady=false;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index adb5ab3..577d98d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -51,7 +51,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothHearingAid) proxy;
             // We just bound to the service, so refresh the UI for any connected HearingAid devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -77,7 +76,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
@@ -234,7 +232,7 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEARING_AID,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index 4879144..c6bb2b3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -59,7 +59,6 @@
 
         @Override
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "Bluetooth service connected");
             mService = (BluetoothHeadsetClient) proxy;
             // We just bound to the service, so refresh the UI for any connected HFP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -80,7 +79,6 @@
 
         @Override
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
index 61e5b6b..4dc050c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
@@ -58,7 +58,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "Bluetooth service connected :-), profile:" + profile);
             mService = (BluetoothHidDevice) proxy;
             // We just bound to the service, so refresh the UI for any connected HID devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -78,7 +77,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "Bluetooth service disconnected, profile:" + profile);
             mIsProfileReady = false;
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index 75d16db..ca840d9a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -33,7 +33,6 @@
  */
 public class HidProfile implements LocalBluetoothProfile {
     private static final String TAG = "HidProfile";
-    private static boolean V = true;
 
     private BluetoothHidHost mService;
     private boolean mIsProfileReady;
@@ -51,7 +50,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothHidHost) proxy;
             // We just bound to the service, so refresh the UI for any connected HID devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -70,7 +68,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
@@ -186,7 +183,7 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HID_HOST,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
index 1e22f44..6acdcac 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
@@ -59,7 +59,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "Bluetooth service connected, profile:" + profile);
             mService = (BluetoothMapClient) proxy;
             // We just bound to the service, so refresh the UI for any connected MAP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -81,7 +80,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "Bluetooth service disconnected, profile:" + profile);
             mProfileManager.callServiceDisconnectedListeners();
             mIsProfileReady=false;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index 7582024..28975d4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -58,7 +58,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "Bluetooth service connected");
             mService = (BluetoothMap) proxy;
             // We just bound to the service, so refresh the UI for any connected MAP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -80,7 +79,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "Bluetooth service disconnected");
             mProfileManager.callServiceDisconnectedListeners();
             mIsProfileReady=false;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
index 7b81162..2d0a090 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
@@ -34,7 +34,6 @@
  */
 public class PanProfile implements LocalBluetoothProfile {
     private static final String TAG = "PanProfile";
-    private static boolean V = true;
 
     private BluetoothPan mService;
     private boolean mIsProfileReady;
@@ -53,13 +52,11 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothPan) proxy;
             mIsProfileReady=true;
         }
 
         public void onServiceDisconnected(int profile) {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
@@ -173,7 +170,7 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.PAN, mService);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index 1f15601..4672393 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -55,7 +55,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "Bluetooth service connected, profile:" + profile);
             mService = (BluetoothPbapClient) proxy;
             // We just bound to the service, so refresh the UI for any connected PBAP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -74,7 +73,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "Bluetooth service disconnected, profile:" + profile);
             mIsProfileReady = false;
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
index adef0841..1b3c453 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
@@ -33,7 +33,6 @@
  */
 public class PbapServerProfile implements LocalBluetoothProfile {
     private static final String TAG = "PbapServerProfile";
-    private static boolean V = true;
 
     private BluetoothPbap mService;
     private boolean mIsProfileReady;
@@ -56,13 +55,11 @@
             implements BluetoothPbap.ServiceListener {
 
         public void onServiceConnected(BluetoothPbap proxy) {
-            if (V) Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothPbap) proxy;
             mIsProfileReady=true;
         }
 
         public void onServiceDisconnected() {
-            if (V) Log.d(TAG,"Bluetooth service disconnected");
             mIsProfileReady=false;
         }
     }
@@ -142,7 +139,7 @@
     }
 
     protected void finalize() {
-        if (V) Log.d(TAG, "finalize()");
+        Log.d(TAG, "finalize()");
         if (mService != null) {
             try {
                 mService.close();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
index b4acc48..ea2ebde 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
@@ -57,7 +57,6 @@
             implements BluetoothProfile.ServiceListener {
 
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "Bluetooth service connected, profile:" + profile);
             mService = (BluetoothSap) proxy;
             // We just bound to the service, so refresh the UI for any connected SAP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -79,7 +78,6 @@
         }
 
         public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "Bluetooth service disconnected, profile:" + profile);
             mProfileManager.callServiceDisconnectedListeners();
             mIsProfileReady=false;
         }
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 3180b47..3379b1b 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -6730,6 +6730,11 @@
     // OS: Q
     ZEN_CUSTOM_SETTINGS_DIALOG = 1612;
 
+    // OPEN: Settings > Developer Options > Game Update Packages
+    // CATEGORY: SETTINGS
+    // OS: Q
+    SETTINGS_GUP_DASHBOARD = 1613;
+
     // ---- End Q Constants, all Q constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index d07cf78..e10e0d6 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1313,16 +1313,17 @@
         }
     }
 
-    public void notifyDataConnection(int state, boolean isDataAllowed,
-            String reason, String apn, String apnType, LinkProperties linkProperties,
-            NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
+    public void notifyDataConnection(int state, boolean isDataAllowed, String apn, String apnType,
+                                     LinkProperties linkProperties,
+                                     NetworkCapabilities networkCapabilities, int networkType,
+                                     boolean roaming) {
         notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state,
-            isDataAllowed,reason, apn, apnType, linkProperties,
-            networkCapabilities, networkType, roaming);
+                isDataAllowed, apn, apnType, linkProperties,
+                networkCapabilities, networkType, roaming);
     }
 
-    public void notifyDataConnectionForSubscriber(int subId, int state,
-            boolean isDataAllowed, String reason, String apn, String apnType,
+    public void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataAllowed,
+                                                  String apn, String apnType,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
             int networkType, boolean roaming) {
         if (!checkNotifyPermission("notifyDataConnection()" )) {
@@ -1331,7 +1332,6 @@
         if (VDBG) {
             log("notifyDataConnectionForSubscriber: subId=" + subId
                 + " state=" + state + " isDataAllowed=" + isDataAllowed
-                + " reason='" + reason
                 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
                 + " mRecords.size()=" + mRecords.size());
         }
@@ -1366,7 +1366,7 @@
                     mDataConnectionNetworkType[phoneId] = networkType;
                 }
                 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
-                        apnType, apn, reason, linkProperties, "");
+                        apnType, apn, linkProperties, "");
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
                             PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
@@ -1381,30 +1381,29 @@
             }
             handleRemoveListLocked();
         }
-        broadcastDataConnectionStateChanged(state, isDataAllowed, reason, apn,
-                apnType, linkProperties, networkCapabilities, roaming, subId);
-        broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason,
+        broadcastDataConnectionStateChanged(state, isDataAllowed, apn, apnType, linkProperties,
+                networkCapabilities, roaming, subId);
+        broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn,
                 linkProperties, "");
     }
 
-    public void notifyDataConnectionFailed(String reason, String apnType) {
+    public void notifyDataConnectionFailed(String apnType) {
          notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                 reason, apnType);
+                 apnType);
     }
 
-    public void notifyDataConnectionFailedForSubscriber(int subId,
-            String reason, String apnType) {
+    public void notifyDataConnectionFailedForSubscriber(int subId, String apnType) {
         if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
             return;
         }
         if (VDBG) {
             log("notifyDataConnectionFailedForSubscriber: subId=" + subId
-                + " reason=" + reason + " apnType=" + apnType);
+                    + " apnType=" + apnType);
         }
         synchronized (mRecords) {
             mPreciseDataConnectionState = new PreciseDataConnectionState(
                     TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                    apnType, "", reason, null, "");
+                    apnType, "", null, "");
             for (Record r : mRecords) {
                 if (r.matchPhoneStateListenerEvent(
                         PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
@@ -1417,9 +1416,9 @@
             }
             handleRemoveListLocked();
         }
-        broadcastDataConnectionFailed(reason, apnType, subId);
+        broadcastDataConnectionFailed(apnType, subId);
         broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, "");
+                TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", null, "");
     }
 
     public void notifyCellLocation(Bundle cellLocation) {
@@ -1529,15 +1528,14 @@
         }
     }
 
-    public void notifyPreciseDataConnectionFailed(String reason, String apnType,
-            String apn, String failCause) {
+    public void notifyPreciseDataConnectionFailed(String apnType, String apn, String failCause) {
         if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
             return;
         }
         synchronized (mRecords) {
             mPreciseDataConnectionState = new PreciseDataConnectionState(
                     TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                    apnType, apn, reason, null, failCause);
+                    apnType, apn, null, failCause);
             for (Record r : mRecords) {
                 if (r.matchPhoneStateListenerEvent(
                         PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
@@ -1551,7 +1549,7 @@
             handleRemoveListLocked();
         }
         broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
+                TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, null, failCause);
     }
 
     @Override
@@ -1881,10 +1879,10 @@
                         android.Manifest.permission.READ_CALL_LOG});
     }
 
-    private void broadcastDataConnectionStateChanged(int state,
-            boolean isDataAllowed,
-            String reason, String apn, String apnType, LinkProperties linkProperties,
-            NetworkCapabilities networkCapabilities, boolean roaming, int subId) {
+    private void broadcastDataConnectionStateChanged(int state, boolean isDataAllowed, String apn,
+                                                     String apnType, LinkProperties linkProperties,
+                                                     NetworkCapabilities networkCapabilities,
+                                                     boolean roaming, 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.
@@ -1894,9 +1892,6 @@
         if (!isDataAllowed) {
             intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
         }
-        if (reason != null) {
-            intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
-        }
         if (linkProperties != null) {
             intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
             String iface = linkProperties.getInterfaceName();
@@ -1915,17 +1910,15 @@
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
-    private void broadcastDataConnectionFailed(String reason, String apnType,
-            int subId) {
+    private void broadcastDataConnectionFailed(String apnType, int subId) {
         Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
-        intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
         intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
     private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
-            int backgroundCallState) {
+                                                  int backgroundCallState) {
         Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
         intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
         intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
@@ -1935,16 +1928,16 @@
     }
 
     private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
-            String apnType, String apn, String reason, LinkProperties linkProperties,
-            String failCause) {
+                                                            String apnType, String apn,
+                                                            LinkProperties linkProperties,
+                                                            String failCause) {
         Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
         intent.putExtra(PhoneConstants.STATE_KEY, state);
         intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
-        if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
         if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
         if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
         if (linkProperties != null) {
-            intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties);
+            intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
         }
         if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
 
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index d133dea..895a86b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1614,13 +1614,6 @@
                 app.addPackage(info.packageName, info.versionCode, mService.mProcessStats);
                 checkSlow(startTime, "startProcess: done, added package to proc");
                 return app;
-            } else if (app.getActiveInstrumentation() != null) {
-                // We don't want to kill running instrumentation.
-                if (DEBUG_PROCESSES) {
-                    Slog.v(TAG_PROCESSES, "Instrumentation already running: " + app);
-                }
-                checkSlow(startTime, "startProcess: keep instrumentation proc");
-                return app;
             }
 
             // An application record is attached to a previous process,
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index d154830..1f0f94a 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.hardware.hdmi.HdmiDeviceInfo;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -316,7 +317,7 @@
      * <p>When ARC is initiated, this port will be used to turn on ARC.
      */
     static final String PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT =
-        "persist.sys.hdmi.property_sytem_audio_device_arc_port";
+            "persist.sys.hdmi.property_sytem_audio_device_arc_port";
 
     /**
      * Property to strip local audio of amplifier and use local speaker
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 3845954..9690ba8 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -95,6 +95,11 @@
         startQueuedActions();
     }
 
+    @Override
+    protected int findKeyReceiverAddress() {
+        return Constants.ADDR_TV;
+    }
+
     @VisibleForTesting
     protected void systemAudioControlOnPowerOn(
             int systemAudioOnPowerOnProp, boolean lastSystemAudioControlStatus) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index f468c0b..3420b26 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -18,6 +18,7 @@
 
 import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
 import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
+
 import static com.android.server.hdmi.Constants.DISABLED;
 import static com.android.server.hdmi.Constants.ENABLED;
 import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
@@ -67,6 +68,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
@@ -76,6 +78,9 @@
 import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
 import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
 import com.android.server.hdmi.HdmiCecLocalDevice.PendingActionClearedCallback;
+
+import libcore.util.EmptyArray;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -85,7 +90,6 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import libcore.util.EmptyArray;
 
 /**
  * Provides a service for sending and processing HDMI control messages,
@@ -1469,12 +1473,12 @@
 
         @Override
         public boolean getSystemAudioMode() {
+            // TODO(shubang): handle getSystemAudioMode() for all device types
             enforceAccessPermission();
             HdmiCecLocalDeviceTv tv = tv();
-            if (tv == null) {
-                return false;
-            }
-            return tv.isSystemAudioActivated();
+            HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem();
+            return (tv != null && tv.isSystemAudioActivated())
+                    || (audioSystem != null && audioSystem.isSystemAudioActivated());
         }
 
         @Override
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index d51da99..052d579 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -40,6 +40,7 @@
 import android.media.AudioSystem;
 import android.media.IAudioService;
 import android.media.IRemoteVolumeController;
+import android.media.Session2Token;
 import android.media.session.IActiveSessionsListener;
 import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
@@ -895,6 +896,21 @@
         }
 
         @Override
+        public void notifySession2Created(Session2Token sessionToken) throws RemoteException {
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (DEBUG) {
+                    Log.d(TAG, "Session2 is created " + sessionToken);
+                }
+                // TODO: Keep the session.
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
         public List<IBinder> getSessions(ComponentName componentName, int userId) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c792863..2060aef 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -24,6 +24,7 @@
 import static android.content.Context.CONTEXT_RESTRICTED;
 import static android.content.Context.DISPLAY_SERVICE;
 import static android.content.Context.WINDOW_SERVICE;
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
@@ -126,6 +127,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
+import android.hardware.hdmi.HdmiAudioSystemClient;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiPlaybackClient;
 import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
@@ -195,6 +197,7 @@
 import com.android.internal.accessibility.AccessibilityShortcutController;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.os.RoSystemProperties;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IShortcutService;
 import com.android.internal.policy.PhoneWindow;
@@ -373,6 +376,7 @@
     private ScreenshotHelper mScreenshotHelper;
     private boolean mHasFeatureWatch;
     private boolean mHasFeatureLeanback;
+    private boolean mHasFeatureHdmiCec;
 
     // Assigned on main thread, accessed on UI thread
     volatile VrManagerInternal mVrManagerInternal;
@@ -1453,7 +1457,7 @@
      */
     private HdmiControl getHdmiControl() {
         if (null == mHdmiControl) {
-            if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
+            if (!mHasFeatureHdmiCec) {
                 return null;
             }
             HdmiControlManager manager = (HdmiControlManager) mContext.getSystemService(
@@ -1689,6 +1693,7 @@
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
         mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
         mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
+        mHasFeatureHdmiCec = mContext.getPackageManager().hasSystemFeature(FEATURE_HDMI_CEC);
         mAccessibilityShortcutController =
                 new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
         mLogger = new MetricsLogger();
@@ -4116,6 +4121,19 @@
     }
 
     private void dispatchDirectAudioEvent(KeyEvent event) {
+        // When System Audio Mode is off, volume keys received by AVR can be either consumed by AVR
+        // or forwarded to the TV. It's up to Amplifier manufacturer’s implementation.
+        HdmiControlManager hdmiControlManager = getHdmiControlManager();
+        if (null != hdmiControlManager
+                && !hdmiControlManager.getSystemAudioMode()
+                && shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff()) {
+            HdmiAudioSystemClient audioSystemClient = hdmiControlManager.getAudioSystemClient();
+            if (audioSystemClient != null) {
+                audioSystemClient.sendKeyEvent(
+                        event.getKeyCode(), event.getAction() == KeyEvent.ACTION_DOWN);
+                return;
+            }
+        }
         if (event.getAction() != KeyEvent.ACTION_DOWN) {
             return;
         }
@@ -4123,6 +4141,7 @@
         int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
                 | AudioManager.FLAG_FROM_KEY;
         String pkgName = mContext.getOpPackageName();
+
         switch (keyCode) {
             case KeyEvent.KEYCODE_VOLUME_UP:
                 try {
@@ -4154,6 +4173,18 @@
         }
     }
 
+    @Nullable
+    private HdmiControlManager getHdmiControlManager() {
+        if (!mHasFeatureHdmiCec) {
+            return null;
+        }
+        return (HdmiControlManager) mContext.getSystemService(HdmiControlManager.class);
+    }
+
+    private boolean shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff() {
+        return RoSystemProperties.CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF;
+    }
+
     void dispatchMediaKeyWithWakeLock(KeyEvent event) {
         if (DEBUG_INPUT) {
             Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index d5286b9..a50ae84 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -947,6 +947,7 @@
         final WindowProcessController wpc =
                 mService.getProcessController(r.processName, r.info.applicationInfo.uid);
 
+        boolean knownToBeDead = false;
         if (wpc != null && wpc.hasThread()) {
             try {
                 if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
@@ -965,6 +966,7 @@
 
             // If a dead object exception was thrown -- fall through to
             // restart the application.
+            knownToBeDead = true;
         }
 
         // Suppress transition until the new activity becomes ready, otherwise the keyguard can
@@ -978,7 +980,7 @@
         // ATMS lock held.
         final Message msg = PooledLambda.obtainMessage(
                 ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
-                r.info.applicationInfo, true, "activity", r.intent.getComponent());
+                r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
         mService.mH.sendMessage(msg);
     }
 
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 294b750..f1e2281 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -1744,8 +1744,8 @@
                     mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
                             USB_GADGET_HAL_DEATH_COOKIE);
                     mCurrentFunctions = UsbManager.FUNCTION_NONE;
-                    mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
                     mCurrentUsbFunctionsRequested = true;
+                    mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
                 }
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
                 updateState(state);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a9a128b..312b318 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2231,7 +2231,7 @@
      * e.g.) To use RSCP by default, set the value to "rscp". The signal strength level will
      * then be determined by #KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY
      * <p>
-     * Currently this only supports the value "rscp"
+     * Currently this supports the value "rscp" and "rssi".
      * @hide
      */
     // FIXME: this key and related keys must not be exposed without a consistent philosophy for
@@ -2875,7 +2875,7 @@
                         -95, /* SIGNAL_STRENGTH_GOOD */
                         -85  /* SIGNAL_STRENGTH_GREAT */
                 });
-        sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, "");
+        sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, "rssi");
         sDefaults.putBoolean(KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL, false);
         sDefaults.putBoolean(KEY_CALL_FORWARDING_OVER_UT_WARNING_BOOL, false);
diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java
index f2c14a1..e6182ed 100644
--- a/telephony/java/android/telephony/CellSignalStrength.java
+++ b/telephony/java/android/telephony/CellSignalStrength.java
@@ -42,6 +42,9 @@
     public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
 
     /** @hide */
+    protected static final int NUM_SIGNAL_STRENGTH_THRESHOLDS = NUM_SIGNAL_STRENGTH_BINS - 1;
+
+    /** @hide */
     public static final String[] SIGNAL_STRENGTH_NAMES = {
         "none", "poor", "moderate", "good", "great"
     };
diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
index 88f6fbc..0760407 100644
--- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
@@ -21,6 +21,7 @@
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 import android.telephony.Rlog;
+import android.text.TextUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -41,8 +42,18 @@
     private static final int WCDMA_RSSI_POOR = -107;
     private static final int WCDMA_RSSI_MIN = -113;
 
-    private static final int WCDMA_RSCP_MIN = -120;
+    private static final int[] sRssiThresholds = new int[]{
+            WCDMA_RSSI_POOR, WCDMA_RSSI_MODERATE, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT};
+
     private static final int WCDMA_RSCP_MAX = -24;
+    private static final int WCDMA_RSCP_GREAT = -85;
+    private static final int WCDMA_RSCP_GOOD = -95;
+    private static final int WCDMA_RSCP_MODERATE = -105;
+    private static final int WCDMA_RSCP_POOR = -115;
+    private static final int WCDMA_RSCP_MIN = -120;
+
+    private static final int[] sRscpThresholds = new int[] {
+            WCDMA_RSCP_POOR, WCDMA_RSCP_MODERATE, WCDMA_RSCP_GOOD, WCDMA_RSCP_GREAT};
 
     // TODO: Because these are used as values in CarrierConfig, they should be exposed somehow.
     /** @hide */
@@ -54,6 +65,9 @@
     /** @hide */
     public static final String LEVEL_CALCULATION_METHOD_RSCP = "rscp";
 
+    // Default to RSSI for backwards compatibility with older devices
+    private static final String sLevelCalculationMethod = LEVEL_CALCULATION_METHOD_RSSI;
+
     private int mRssi; // in dBm [-113, 51] or CellInfo.UNAVAILABLE if unknown
     private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
                                // CellInfo.UNAVAILABLE if unknown
@@ -121,10 +135,6 @@
         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
-    private static final String sLevelCalculationMethod = LEVEL_CALCULATION_METHOD_RSSI;
-    private static final int[] sThresholds = new int[]{
-            WCDMA_RSSI_POOR, WCDMA_RSSI_GOOD, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT};
-
     /**
      * Retrieve an abstract level value for the overall signal strength.
      *
@@ -140,41 +150,46 @@
     @Override
     public void updateLevel(PersistableBundle cc, ServiceState ss) {
         String calcMethod;
-        int[] thresholds;
+        int[] rscpThresholds;
 
         if (cc == null) {
             calcMethod = sLevelCalculationMethod;
-            thresholds = sThresholds;
+            rscpThresholds = sRscpThresholds;
         } else {
             // TODO: abstract this entire thing into a series of functions
             calcMethod = cc.getString(
                     CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
                     sLevelCalculationMethod);
-            thresholds = cc.getIntArray(
+            if (TextUtils.isEmpty(calcMethod)) calcMethod = sLevelCalculationMethod;
+            rscpThresholds = cc.getIntArray(
                     CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY);
-            if (thresholds == null) thresholds = sThresholds;
+            if (rscpThresholds == null || rscpThresholds.length != NUM_SIGNAL_STRENGTH_THRESHOLDS) {
+                rscpThresholds = sRscpThresholds;
+            }
         }
 
-        int level = thresholds.length;
+        int level = NUM_SIGNAL_STRENGTH_THRESHOLDS;
         switch (calcMethod) {
             case LEVEL_CALCULATION_METHOD_RSCP:
                 if (mRscp < WCDMA_RSCP_MIN || mRscp > WCDMA_RSCP_MAX) {
                     mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                     return;
                 }
-                while (level > 0 && mRscp < thresholds[level - 1]) level--;
+                while (level > 0 && mRscp < rscpThresholds[level - 1]) level--;
                 mLevel = level;
                 return;
+            default:
+                loge("Invalid Level Calculation Method for CellSignalStrengthWcdma = "
+                        + calcMethod);
+                /** fall through */
             case LEVEL_CALCULATION_METHOD_RSSI:
                 if (mRssi < WCDMA_RSSI_MIN || mRssi > WCDMA_RSSI_MAX) {
                     mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                     return;
                 }
-                while (level > 0 && mRssi < thresholds[level - 1]) level--;
+                while (level > 0 && mRssi < sRssiThresholds[level - 1]) level--;
                 mLevel = level;
                 return;
-            default:
-                mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
         }
     }
 
@@ -204,7 +219,7 @@
     }
 
     /**
-     * Get the signal strength as dBm
+     * Get the RSSI as dBm
      *
      * @hide
      */
@@ -214,12 +229,32 @@
 
     /**
      * Get the RSCP as dBm
+     *
      * @hide
      */
     public int getRscp() {
         return mRscp;
     }
 
+    /**
+     * Get the Ec/No as dB
+     *
+     * @hide
+     */
+    public int getEcNo() {
+        return mEcNo;
+    }
+
+    /**
+     * Return the Bit Error Rate
+     *
+     * @returns the bit error rate (0-7, 99) as defined in TS 27.007 8.5 or UNAVAILABLE.
+     * @hide
+     */
+    public int getBitErrorRate() {
+        return mBitErrorRate;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(mRssi, mBitErrorRate, mRscp, mEcNo, mLevel);
@@ -304,9 +339,16 @@
     };
 
     /**
-     * log
+     * log warning
      */
     private static void log(String s) {
         Rlog.w(LOG_TAG, s);
     }
+
+    /**
+     * log error
+     */
+    private static void loge(String s) {
+        Rlog.e(LOG_TAG, s);
+    }
 }
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index b258f52..8373899 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -17,10 +17,11 @@
 package android.telephony;
 
 import android.annotation.UnsupportedAppUsage;
+import android.net.LinkProperties;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.telephony.TelephonyManager;
-import android.net.LinkProperties;
+
+import java.util.Objects;
 
 /**
  * Contains precise data connection state.
@@ -32,7 +33,6 @@
  *   <li>Network type of the connection.
  *   <li>APN type.
  *   <li>APN.
- *   <li>Data connection change reason.
  *   <li>The properties of the network link.
  *   <li>Data connection fail cause.
  * </ul>
@@ -45,7 +45,6 @@
     private int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
     private String mAPNType = "";
     private String mAPN = "";
-    private String mReason = "";
     private LinkProperties mLinkProperties = null;
     private String mFailCause = "";
 
@@ -55,14 +54,12 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public PreciseDataConnectionState(int state, int networkType,
-            String apnType, String apn, String reason,
-            LinkProperties linkProperties, String failCause) {
+    public PreciseDataConnectionState(int state, int networkType, String apnType, String apn,
+                                      LinkProperties linkProperties, String failCause) {
         mState = state;
         mNetworkType = networkType;
         mAPNType = apnType;
         mAPN = apn;
-        mReason = reason;
         mLinkProperties = linkProperties;
         mFailCause = failCause;
     }
@@ -83,7 +80,6 @@
         mNetworkType = in.readInt();
         mAPNType = in.readString();
         mAPN = in.readString();
-        mReason = in.readString();
         mLinkProperties = (LinkProperties)in.readParcelable(null);
         mFailCause = in.readString();
     }
@@ -144,14 +140,6 @@
     }
 
     /**
-     * Get data connection change reason.
-     */
-    @UnsupportedAppUsage
-    public String getDataConnectionChangeReason() {
-        return mReason;
-    }
-
-    /**
      * Get the properties of the network link.
      */
     @UnsupportedAppUsage
@@ -178,7 +166,6 @@
         out.writeInt(mNetworkType);
         out.writeString(mAPNType);
         out.writeString(mAPN);
-        out.writeString(mReason);
         out.writeParcelable(mLinkProperties, flags);
         out.writeString(mFailCause);
     }
@@ -197,16 +184,7 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + mState;
-        result = prime * result + mNetworkType;
-        result = prime * result + ((mAPNType == null) ? 0 : mAPNType.hashCode());
-        result = prime * result + ((mAPN == null) ? 0 : mAPN.hashCode());
-        result = prime * result + ((mReason == null) ? 0 : mReason.hashCode());
-        result = prime * result + ((mLinkProperties == null) ? 0 : mLinkProperties.hashCode());
-        result = prime * result + ((mFailCause == null) ? 0 : mFailCause.hashCode());
-        return result;
+        return Objects.hash(mState, mNetworkType, mAPNType, mAPN, mLinkProperties, mFailCause);
     }
 
     @Override
@@ -252,13 +230,6 @@
         if (mNetworkType != other.mNetworkType) {
             return false;
         }
-        if (mReason == null) {
-            if (other.mReason != null) {
-                return false;
-            }
-        } else if (!mReason.equals(other.mReason)) {
-            return false;
-        }
         if (mState != other.mState) {
             return false;
         }
@@ -273,7 +244,6 @@
         sb.append(", Network type: " + mNetworkType);
         sb.append(", APN type: " + mAPNType);
         sb.append(", APN: " + mAPN);
-        sb.append(", Change reason: " + mReason);
         sb.append(", Link properties: " + mLinkProperties);
         sb.append(", Fail cause: " + mFailCause);
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4598afa..8dfdb2f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -772,7 +772,6 @@
      * The {@link #EXTRA_DATA_NETWORK_TYPE} extra indicates the connection network type.
      * The {@link #EXTRA_DATA_APN_TYPE} extra indicates the APN type.
      * The {@link #EXTRA_DATA_APN} extra indicates the APN.
-     * The {@link #EXTRA_DATA_CHANGE_REASON} extra indicates the connection change reason.
      * The {@link #EXTRA_DATA_IFACE_PROPERTIES} extra indicates the connection interface.
      * The {@link #EXTRA_DATA_FAILURE_CAUSE} extra indicates the connection fail cause.
      *
@@ -783,7 +782,6 @@
      * @see #EXTRA_DATA_NETWORK_TYPE
      * @see #EXTRA_DATA_APN_TYPE
      * @see #EXTRA_DATA_APN
-     * @see #EXTRA_DATA_CHANGE_REASON
      * @see #EXTRA_DATA_IFACE
      * @see #EXTRA_DATA_FAILURE_CAUSE
      * @hide
@@ -873,18 +871,6 @@
 
     /**
      * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
-     * for an String representation of the change reason.
-     *
-     * <p class="note">
-     * Retrieve with
-     * {@link android.content.Intent#getStringExtra(String name)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_DATA_CHANGE_REASON = PhoneConstants.STATE_CHANGE_REASON_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">
diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.java b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
index 5122c7d..709b3aa 100644
--- a/telephony/java/android/telephony/ims/Rcs1To1Thread.java
+++ b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
@@ -23,6 +23,10 @@
  * @hide - TODO(sahinc) make this public
  */
 public class Rcs1To1Thread extends RcsThread {
+    public Rcs1To1Thread(int threadId) {
+        super(threadId);
+    }
+
     public static final Creator<Rcs1To1Thread> CREATOR = new Creator<Rcs1To1Thread>() {
         @Override
         public Rcs1To1Thread createFromParcel(Parcel in) {
@@ -36,6 +40,7 @@
     };
 
     protected Rcs1To1Thread(Parcel in) {
+        super(in);
     }
 
     @Override
@@ -45,5 +50,7 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(RCS_1_TO_1_TYPE);
+        super.writeToParcel(dest, flags);
     }
 }
diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.java b/telephony/java/android/telephony/ims/RcsGroupThread.java
index 150c4d4..d954b2d 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThread.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThread.java
@@ -36,6 +36,7 @@
     };
 
     protected RcsGroupThread(Parcel in) {
+        super(in);
     }
 
     @Override
@@ -45,5 +46,7 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(RCS_GROUP_TYPE);
+        super.writeToParcel(dest, flags);
     }
 }
diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java
index 4198c78..1bf6ffd 100644
--- a/telephony/java/android/telephony/ims/RcsMessageStore.java
+++ b/telephony/java/android/telephony/ims/RcsMessageStore.java
@@ -16,6 +16,8 @@
 
 package android.telephony.ims;
 
+import android.annotation.Nullable;
+import android.annotation.WorkerThread;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Rlog;
@@ -27,26 +29,93 @@
  * @hide - TODO make this public
  */
 public class RcsMessageStore {
-    private static final String TAG = "RcsMessageStore";
-    private static final boolean VDBG = false;
+    static final String TAG = "RcsMessageStore";
 
     /**
-     * Delete the RcsThread identified by the given threadId.
+     * Returns the first chunk of existing {@link RcsThread}s in the common storage.
+     * @param queryParameters Parameters to specify to return a subset of all RcsThreads.
+     *                        Passing a value of null will return all threads.
+     */
+    @WorkerThread
+    public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParameters queryParameters) {
+        try {
+            IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
+            if (iRcs != null) {
+                return iRcs.getRcsThreads(queryParameters);
+            }
+        } catch (RemoteException re) {
+            Rlog.e(TAG, "RcsMessageStore: Exception happened during getRcsThreads", re);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the next chunk of {@link RcsThread}s in the common storage.
+     * @param continuationToken A token to continue the query to get the next chunk. This is
+     *                          obtained through {@link RcsThreadQueryResult#nextChunkToken}.
+     */
+    @WorkerThread
+    public RcsThreadQueryResult getRcsThreads(RcsThreadQueryContinuationToken continuationToken) {
+        try {
+            IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
+            if (iRcs != null) {
+                return iRcs.getRcsThreadsWithToken(continuationToken);
+            }
+        } catch (RemoteException re) {
+            Rlog.e(TAG, "RcsMessageStore: Exception happened during getRcsThreads", re);
+        }
+
+        return null;
+    }
+
+    /**
+     * Creates a new 1 to 1 thread with the given participant and persists it in the storage.
+     */
+    @WorkerThread
+    public Rcs1To1Thread createRcs1To1Thread(RcsParticipant recipient) {
+        try {
+            IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
+            if (iRcs != null) {
+                return iRcs.createRcs1To1Thread(recipient);
+            }
+        } catch (RemoteException re) {
+            Rlog.e(TAG, "RcsMessageStore: Exception happened during createRcs1To1Thread", re);
+        }
+
+        return null;
+    }
+
+    /**
+     * Delete the {@link RcsThread} identified by the given threadId.
      * @param threadId threadId of the thread to be deleted.
      */
+    @WorkerThread
     public void deleteThread(int threadId) {
-        if (VDBG) logd("deleteThread: threadId: " + threadId);
         try {
             IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
             if (iRcs != null) {
                 iRcs.deleteThread(threadId);
             }
         } catch (RemoteException re) {
-
+            Rlog.e(TAG, "RcsMessageStore: Exception happened during deleteThread", re);
         }
     }
 
-    private static void logd(String msg) {
-        Rlog.d(TAG, msg);
+    /**
+     * Creates a new participant and persists it in the storage.
+     * @param canonicalAddress The defining address (e.g. phone number) of the participant.
+     */
+    public RcsParticipant createRcsParticipant(String canonicalAddress) {
+        try {
+            IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
+            if (iRcs != null) {
+                return iRcs.createRcsParticipant(canonicalAddress);
+            }
+        } catch (RemoteException re) {
+            Rlog.e(TAG, "RcsMessageStore: Exception happened during createRcsParticipant", re);
+        }
+
+        return null;
     }
 }
diff --git a/telephony/java/android/telephony/ims/RcsParticipant.java b/telephony/java/android/telephony/ims/RcsParticipant.java
index 318dba3..70500aa 100644
--- a/telephony/java/android/telephony/ims/RcsParticipant.java
+++ b/telephony/java/android/telephony/ims/RcsParticipant.java
@@ -23,6 +23,16 @@
  * @hide - TODO(sahinc) make this public
  */
 public class RcsParticipant implements Parcelable {
+    /**
+     * Returns the row id of this participant.
+     *
+     * TODO(sahinc) implement
+     * @hide
+     */
+    public int getId() {
+        return 12345;
+    }
+
     public static final Creator<RcsParticipant> CREATOR = new Creator<RcsParticipant>() {
         @Override
         public RcsParticipant createFromParcel(Parcel in) {
diff --git a/telephony/java/android/telephony/ims/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java
index 2969ffd..c0a0d94 100644
--- a/telephony/java/android/telephony/ims/RcsThread.java
+++ b/telephony/java/android/telephony/ims/RcsThread.java
@@ -16,7 +16,9 @@
 
 package android.telephony.ims;
 
+import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Log;
 
 /**
  * RcsThread represents a single RCS conversation thread. It holds messages that were sent and
@@ -24,5 +26,50 @@
  * @hide - TODO(sahinc) make this public
  */
 public abstract class RcsThread implements Parcelable {
+    // Since this is an abstract class that gets parcelled, the sub-classes need to write these
+    // magic values into the parcel so that we know which type to unparcel into.
+    protected static final int RCS_1_TO_1_TYPE = 998;
+    protected static final int RCS_GROUP_TYPE = 999;
 
+    protected int mThreadId;
+
+    protected RcsThread(int threadId) {
+        mThreadId = threadId;
+    }
+
+    protected RcsThread(Parcel in) {
+        mThreadId = in.readInt();
+    }
+
+    public static final Creator<RcsThread> CREATOR = new Creator<RcsThread>() {
+        @Override
+        public RcsThread createFromParcel(Parcel in) {
+            int type = in.readInt();
+
+            switch (type) {
+                case RCS_1_TO_1_TYPE:
+                    return new Rcs1To1Thread(in);
+                case RCS_GROUP_TYPE:
+                    return new RcsGroupThread(in);
+                default:
+                    Log.e(RcsMessageStore.TAG, "Cannot unparcel RcsThread, wrong type: " + type);
+            }
+            return null;
+        }
+
+        @Override
+        public RcsThread[] newArray(int size) {
+            return new RcsThread[0];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mThreadId);
+    }
 }
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl
new file mode 100644
index 0000000..7bcebfa
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.telephony.ims;
+
+parcelable RcsThreadQueryContinuationToken;
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java
new file mode 100644
index 0000000..931e93d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A continuation token to provide for {@link RcsMessageStore#getRcsThreads}. Use this token to
+ * break large queries into manageable chunks
+ * @hide - TODO make this public
+ */
+public class RcsThreadQueryContinuationToken implements Parcelable {
+    protected RcsThreadQueryContinuationToken(Parcel in) {
+    }
+
+    public static final Creator<RcsThreadQueryContinuationToken> CREATOR =
+            new Creator<RcsThreadQueryContinuationToken>() {
+                @Override
+                public RcsThreadQueryContinuationToken createFromParcel(Parcel in) {
+                    return new RcsThreadQueryContinuationToken(in);
+                }
+
+                @Override
+                public RcsThreadQueryContinuationToken[] newArray(int size) {
+                    return new RcsThreadQueryContinuationToken[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl
new file mode 100644
index 0000000..feb2d4d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.telephony.ims;
+
+parcelable RcsThreadQueryParameters;
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java
new file mode 100644
index 0000000..f2c4ab1
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.CheckResult;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * The parameters to pass into {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} in
+ * order to select a subset of {@link RcsThread}s present in the message store.
+ * @hide TODO - make the Builder and builder() public. The rest should stay internal only.
+ */
+public class RcsThreadQueryParameters implements Parcelable {
+    private final boolean mIsGroup;
+    private final Set<RcsParticipant> mRcsParticipants;
+    private final int mLimit;
+    private final boolean mIsAscending;
+
+    RcsThreadQueryParameters(boolean isGroup, Set<RcsParticipant> participants, int limit,
+            boolean isAscending) {
+        mIsGroup = isGroup;
+        mRcsParticipants = participants;
+        mLimit = limit;
+        mIsAscending = isAscending;
+    }
+
+    /**
+     * Returns a new builder to build a query with.
+     * TODO - make public
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
+     * the list of participants.
+     * @hide
+     */
+    public Set<RcsParticipant> getRcsParticipants() {
+        return mRcsParticipants;
+    }
+
+    /**
+     * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
+     * whether group threads should be queried
+     * @hide
+     */
+    public boolean isGroupThread() {
+        return mIsGroup;
+    }
+
+    /**
+     * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
+     * the number of tuples the result query should be limited to.
+     */
+    public int getLimit() {
+        return mLimit;
+    }
+
+    /**
+     * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to
+     * determine the sort order.
+     */
+    public boolean isAscending() {
+        return mIsAscending;
+    }
+
+    /**
+     * A helper class to build the {@link RcsThreadQueryParameters}.
+     */
+    public static class Builder {
+        private boolean mIsGroupThread;
+        private Set<RcsParticipant> mParticipants;
+        private int mLimit = 100;
+        private boolean mIsAscending;
+
+        /**
+         * Package private constructor for {@link RcsThreadQueryParameters.Builder}. To obtain this,
+         * {@link RcsThreadQueryParameters#builder()} needs to be called.
+         */
+        Builder() {
+            mParticipants = new HashSet<>();
+        }
+
+        /**
+         * Limits the query to only return group threads.
+         * @param isGroupThread Whether to limit the query result to group threads.
+         * @return The same instance of the builder to chain parameters.
+         */
+        @CheckResult
+        public Builder isGroupThread(boolean isGroupThread) {
+            mIsGroupThread = isGroupThread;
+            return this;
+        }
+
+        /**
+         * Limits the query to only return threads that contain the given participant.
+         * @param participant The participant that must be included in all of the returned threads.
+         * @return The same instance of the builder to chain parameters.
+         */
+        @CheckResult
+        public Builder withParticipant(RcsParticipant participant) {
+            mParticipants.add(participant);
+            return this;
+        }
+
+        /**
+         * Limits the query to only return threads that contain the given list of participants.
+         * @param participants An iterable list of participants that must be included in all of the
+         *                     returned threads.
+         * @return The same instance of the builder to chain parameters.
+         */
+        @CheckResult
+        public Builder withParticipants(Iterable<RcsParticipant> participants) {
+            for (RcsParticipant participant : participants) {
+                mParticipants.add(participant);
+            }
+            return this;
+        }
+
+        /**
+         * Desired number of threads to be returned from the query. Passing in 0 will return all
+         * existing threads at once. The limit defaults to 100.
+         * @param limit The number to limit the query result to.
+         * @return The same instance of the builder to chain parameters.
+         * @throws InvalidParameterException If the given limit is negative.
+         */
+        @CheckResult
+        public Builder limitResultsTo(int limit) throws InvalidParameterException {
+            if (limit < 0) {
+                throw new InvalidParameterException("The query limit must be non-negative");
+            }
+
+            mLimit = limit;
+            return this;
+        }
+
+        /**
+         * Sorts the results returned from the query via thread IDs.
+         *
+         * TODO - add sorting support for other fields
+         *
+         * @param isAscending whether to sort in ascending order or not
+         * @return The same instance of the builder to chain parameters.
+         */
+        @CheckResult
+        public Builder sort(boolean isAscending) {
+            mIsAscending = isAscending;
+            return this;
+        }
+
+        /**
+         * Builds the {@link RcsThreadQueryParameters} to use in
+         * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)}
+         *
+         * @return An instance of {@link RcsThreadQueryParameters} to use with the thread query.
+         */
+        public RcsThreadQueryParameters build() {
+            return new RcsThreadQueryParameters(
+                    mIsGroupThread, mParticipants, mLimit, mIsAscending);
+        }
+    }
+
+    /**
+     * Parcelable boilerplate below.
+     */
+    protected RcsThreadQueryParameters(Parcel in) {
+        mIsGroup = in.readBoolean();
+
+        ArrayList<RcsParticipant> participantArrayList = new ArrayList<>();
+        in.readTypedList(participantArrayList, RcsParticipant.CREATOR);
+        mRcsParticipants = new HashSet<>(participantArrayList);
+
+        mLimit = in.readInt();
+        mIsAscending = in.readBoolean();
+    }
+
+    public static final Creator<RcsThreadQueryParameters> CREATOR =
+            new Creator<RcsThreadQueryParameters>() {
+                @Override
+                public RcsThreadQueryParameters createFromParcel(Parcel in) {
+                    return new RcsThreadQueryParameters(in);
+                }
+
+                @Override
+                public RcsThreadQueryParameters[] newArray(int size) {
+                    return new RcsThreadQueryParameters[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBoolean(mIsGroup);
+        dest.writeTypedList(new ArrayList<>(mRcsParticipants));
+        dest.writeInt(mLimit);
+        dest.writeBoolean(mIsAscending);
+    }
+
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl
new file mode 100644
index 0000000..4b06529
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.telephony.ims;
+
+parcelable RcsThreadQueryResult;
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
new file mode 100644
index 0000000..47715f8
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+
+/**
+ * The result of a {@link RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken,
+ * RcsThreadQueryParameters)}
+ * call. This class allows getting the token for querying the next batch of threads in order to
+ * prevent handling large amounts of data at once.
+ *
+ * @hide
+ */
+public class RcsThreadQueryResult implements Parcelable {
+    private RcsThreadQueryContinuationToken mContinuationToken;
+    private List<RcsThread> mRcsThreads;
+
+    /**
+     * Internal constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
+     * to create query results
+     *
+     * @hide
+     */
+    public RcsThreadQueryResult(
+            RcsThreadQueryContinuationToken continuationToken, List<RcsThread> rcsThreads) {
+        mContinuationToken = continuationToken;
+        mRcsThreads = rcsThreads;
+    }
+
+    /**
+     * Returns a token to call
+     * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken)}
+     * to get the next batch of {@link RcsThread}s.
+     */
+    public RcsThreadQueryContinuationToken nextChunkToken() {
+        return mContinuationToken;
+    }
+
+    /**
+     * Returns all the RcsThreads in the current query result. Call {@link
+     * RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken)} to get the next batch of
+     * {@link RcsThread}s.
+     */
+    public List<RcsThread> getThreads() {
+        return mRcsThreads;
+    }
+
+    protected RcsThreadQueryResult(Parcel in) {
+        // TODO - implement
+    }
+
+    public static final Creator<RcsThreadQueryResult> CREATOR =
+            new Creator<RcsThreadQueryResult>() {
+                @Override
+                public RcsThreadQueryResult createFromParcel(Parcel in) {
+                    return new RcsThreadQueryResult(in);
+                }
+
+                @Override
+                public RcsThreadQueryResult[] newArray(int size) {
+                    return new RcsThreadQueryResult[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        // TODO - implement
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
index b2e2fad..9badac5 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcs.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
@@ -16,14 +16,29 @@
 
 package android.telephony.ims.aidl;
 
+import android.telephony.ims.RcsParticipant;
+import android.telephony.ims.Rcs1To1Thread;
+import android.telephony.ims.RcsThreadQueryContinuationToken;
+import android.telephony.ims.RcsThreadQueryParameters;
+import android.telephony.ims.RcsThreadQueryResult;
+
 /**
  * RPC definition between RCS storage APIs and phone process.
  * {@hide}
  */
 interface IRcs {
     // RcsMessageStore APIs
+    RcsThreadQueryResult getRcsThreads(in RcsThreadQueryParameters queryParameters);
+
+    RcsThreadQueryResult getRcsThreadsWithToken(
+        in RcsThreadQueryContinuationToken continuationToken);
+
     void deleteThread(int threadId);
 
+    Rcs1To1Thread createRcs1To1Thread(in RcsParticipant participant);
+
+    RcsParticipant createRcsParticipant(String canonicalAddress);
+
     // RcsThread APIs
     int getMessageCount(int rcsThreadId);
 }
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index d9f5c3f..02a6f31 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -50,13 +50,13 @@
     void notifyDataActivity(int state);
     void notifyDataActivityForSubscriber(in int subId, int state);
     void notifyDataConnection(int state, boolean isDataConnectivityPossible,
-            String reason, String apn, String apnType, in LinkProperties linkProperties,
+            String apn, String apnType, in LinkProperties linkProperties,
             in NetworkCapabilities networkCapabilities, int networkType, boolean roaming);
     void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataConnectivityPossible,
-            String reason, String apn, String apnType, in LinkProperties linkProperties,
+            String apn, String apnType, in LinkProperties linkProperties,
             in NetworkCapabilities networkCapabilities, int networkType, boolean roaming);
-    void notifyDataConnectionFailed(String reason, String apnType);
-    void notifyDataConnectionFailedForSubscriber(int subId, String reason, String apnType);
+    void notifyDataConnectionFailed(String apnType);
+    void notifyDataConnectionFailedForSubscriber(int subId, String apnType);
     void notifyCellLocation(in Bundle cellLocation);
     void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation);
     void notifyOtaspChanged(in int otaspMode);
@@ -67,7 +67,7 @@
     void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
             int backgroundCallState);
     void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause);
-    void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
+    void notifyPreciseDataConnectionFailed(String apnType, String apn,
             String failCause);
     void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo);
     void notifySrvccStateChanged(in int subId, in int lteState);
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 21f3b92..e87d28c 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -79,8 +79,6 @@
     public static final int SIM_ACTIVATION_TYPE_DATA = 1;
 
     public static final String PHONE_NAME_KEY = "phoneName";
-    public static final String FAILURE_REASON_KEY = "reason";
-    public static final String STATE_CHANGE_REASON_KEY = "reason";
     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";
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index 0ac35bc..e9a5ff7 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -119,7 +119,7 @@
 
         @Override
         public IBinder asBinder() {
-            throw new UnsupportedOperationException();
+            return MockContentProvider.this.getIContentProviderBinder();
         }
 
         @Override
@@ -279,6 +279,13 @@
     }
 
     /**
+     * @hide
+     */
+    public IBinder getIContentProviderBinder() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    /**
      * Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use
      * when directly instantiating the provider for testing.
      *
diff --git a/tests/RcsTests/Android.mk b/tests/RcsTests/Android.mk
index adc7cab..7b348d7 100644
--- a/tests/RcsTests/Android.mk
+++ b/tests/RcsTests/Android.mk
@@ -11,7 +11,7 @@
 
 LOCAL_CERTIFICATE := platform
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_STATIC_JAVA_LIBRARIES := junit android-support-test mockito-target-minus-junit4
+LOCAL_STATIC_JAVA_LIBRARIES := junit android-support-test mockito-target-minus-junit4 truth-prebuilt
 
 include $(BUILD_PACKAGE)
 
diff --git a/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java
similarity index 97%
rename from tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java
rename to tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java
index 290e04c..44277ed 100644
--- a/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.tests.rcs;
+package com.android.tests.ims;
 
 import android.support.test.runner.AndroidJUnit4;
 import android.telephony.ims.RcsMessageStore;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java
new file mode 100644
index 0000000..a890a38
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.ims;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.RcsParticipant;
+import android.telephony.ims.RcsThreadQueryParameters;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsThreadQueryParametersTest {
+    private RcsThreadQueryParameters mRcsThreadQueryParameters;
+    @Mock RcsParticipant mMockParticipant;
+
+    @Test
+    public void testUnparceling() {
+        String key = "some key";
+        mRcsThreadQueryParameters = RcsThreadQueryParameters.builder()
+                .isGroupThread(true)
+                .withParticipant(mMockParticipant)
+                .limitResultsTo(50)
+                .sort(true)
+                .build();
+
+        Bundle bundle = new Bundle();
+        bundle.putParcelable(key, mRcsThreadQueryParameters);
+        mRcsThreadQueryParameters = bundle.getParcelable(key);
+
+        assertThat(mRcsThreadQueryParameters.isGroupThread()).isTrue();
+        assertThat(mRcsThreadQueryParameters.getRcsParticipants()).contains(mMockParticipant);
+        assertThat(mRcsThreadQueryParameters.getLimit()).isEqualTo(50);
+        assertThat(mRcsThreadQueryParameters.isAscending()).isTrue();
+    }
+}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
index 01feb1e..72e57a1 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -17,15 +17,15 @@
 package android.net.wifi.p2p;
 
 import android.annotation.UnsupportedAppUsage;
-import android.os.Parcelable;
 import android.os.Parcel;
+import android.os.Parcelable;
 
 import java.util.ArrayList;
-import java.util.List;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.regex.Pattern;
+import java.util.List;
 import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * A class representing a Wi-Fi P2p group. A p2p group consists of a single group
@@ -67,6 +67,9 @@
     /** The network id in the wpa_supplicant */
     private int mNetId;
 
+    /** The frequency used by this group */
+    private int mFrequency;
+
     /** P2P group started string pattern */
     private static final Pattern groupStartedPattern = Pattern.compile(
         "ssid=\"(.+)\" " +
@@ -116,8 +119,9 @@
             }
 
             mNetworkName = match.group(1);
-            //freq and psk are unused right now
-            //int freq = Integer.parseInt(match.group(2));
+            // It throws NumberFormatException if the string cannot be parsed as an integer.
+            mFrequency = Integer.parseInt(match.group(2));
+            // psk is unused right now
             //String psk = match.group(3);
             mPassphrase = match.group(4);
             mOwner = new WifiP2pDevice(match.group(5));
@@ -269,6 +273,16 @@
         this.mNetId = netId;
     }
 
+    /** Get the operating frequency of the p2p group */
+    public int getFrequency() {
+        return mFrequency;
+    }
+
+    /** @hide */
+    public void setFrequency(int freq) {
+        this.mFrequency = freq;
+    }
+
     public String toString() {
         StringBuffer sbuf = new StringBuffer();
         sbuf.append("network: ").append(mNetworkName);
@@ -279,6 +293,7 @@
         }
         sbuf.append("\n interface: ").append(mInterface);
         sbuf.append("\n networkId: ").append(mNetId);
+        sbuf.append("\n frequency: ").append(mFrequency);
         return sbuf.toString();
     }
 
@@ -297,6 +312,7 @@
             mPassphrase = source.getPassphrase();
             mInterface = source.getInterface();
             mNetId = source.getNetworkId();
+            mFrequency = source.getFrequency();
         }
     }
 
@@ -312,6 +328,7 @@
         dest.writeString(mPassphrase);
         dest.writeString(mInterface);
         dest.writeInt(mNetId);
+        dest.writeInt(mFrequency);
     }
 
     /** Implement the Parcelable interface */
@@ -329,6 +346,7 @@
                 group.setPassphrase(in.readString());
                 group.setInterface(in.readString());
                 group.setNetworkId(in.readInt());
+                group.setFrequency(in.readInt());
                 return group;
             }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 068b959..1bed914 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -1281,7 +1281,16 @@
         c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener));
     }
 
-    /** @hide */
+    /**
+     * Force p2p to enter or exit listen state
+     *
+     * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}
+     * @param enable enables or disables listening
+     * @param listener for callbacks on success or failure. Can be null.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void listen(Channel c, boolean enable, ActionListener listener) {
         checkChannel(c);
         c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN,