Merge "AAPT2: Clean up R JavaDoc generation" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index f346e0b..1c4f85b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4915,6 +4915,7 @@
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
     field public static final int DEFAULT_SOUND = 1; // 0x1
     field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
     field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
     field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
@@ -4923,12 +4924,14 @@
     field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
     field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
     field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
     field public static final java.lang.String EXTRA_PEOPLE = "android.people";
     field public static final java.lang.String EXTRA_PICTURE = "android.picture";
     field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
     field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
     field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
     field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
     field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
     field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
     field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -4937,6 +4940,7 @@
     field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
     field public static final java.lang.String EXTRA_TEXT = "android.text";
     field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
     field public static final java.lang.String EXTRA_TITLE = "android.title";
     field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
@@ -5176,6 +5180,32 @@
     method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
   }
 
+  public static class Notification.MessagingStyle extends android.app.Notification.Style {
+    ctor public Notification.MessagingStyle(java.lang.CharSequence);
+    method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message);
+    method public boolean getAllowGeneratedReplies();
+    method public java.lang.CharSequence getConversationTitle();
+    method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages();
+    method public java.lang.CharSequence getUserDisplayName();
+    method public android.app.Notification.MessagingStyle setAllowGeneratedReplies(boolean);
+    method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+    ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public int describeContents();
+    method public java.lang.String getDataMimeType();
+    method public android.net.Uri getDataUri();
+    method public java.lang.CharSequence getSender();
+    method public java.lang.CharSequence getText();
+    method public long getTimestamp();
+    method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
+  }
+
   public static abstract class Notification.Style {
     ctor public Notification.Style();
     method public android.app.Notification build();
@@ -7673,8 +7703,6 @@
     method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
-    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
-    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
@@ -19221,7 +19249,7 @@
     field public static final int ADR_STATE_VALID = 1; // 0x1
     field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
     field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
-    field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+    field public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2; // 0x2
     field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
     field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
     field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
@@ -19241,21 +19269,20 @@
   }
 
   public final class GnssMeasurementsEvent implements android.os.Parcelable {
-    ctor public GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]);
     method public int describeContents();
     method public android.location.GnssClock getClock();
     method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
-    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
-    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
-    field public static final int STATUS_READY = 1; // 0x1
   }
 
   public static abstract class GnssMeasurementsEvent.Callback {
     ctor public GnssMeasurementsEvent.Callback();
     method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
     method public void onStatusChanged(int);
+    field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
   }
 
   public final class GnssNavigationMessage implements android.os.Parcelable {
@@ -19283,36 +19310,24 @@
     field public static final int TYPE_UNKNOWN = 0; // 0x0
   }
 
-  public final class GnssNavigationMessageEvent implements android.os.Parcelable {
-    ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
-    method public int describeContents();
-    method public android.location.GnssNavigationMessage getNavigationMessage();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
-    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+  public static abstract class GnssNavigationMessage.Callback {
+    ctor public GnssNavigationMessage.Callback();
+    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessage);
+    method public void onStatusChanged(int);
+    field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
     field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
     field public static final int STATUS_READY = 1; // 0x1
   }
 
-  public static abstract class GnssNavigationMessageEvent.Callback {
-    ctor public GnssNavigationMessageEvent.Callback();
-    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
-    method public void onStatusChanged(int);
-  }
-
-  public abstract interface GnssNmeaListener {
-    method public abstract void onNmeaReceived(long, java.lang.String);
-  }
-
   public final class GnssStatus {
     method public float getAzimuthDegrees(int);
     method public float getCn0DbHz(int);
     method public int getConstellationType(int);
     method public float getElevationDegrees(int);
-    method public int getNumSatellites();
+    method public int getSatelliteCount();
     method public int getSvid(int);
-    method public boolean hasAlmanac(int);
-    method public boolean hasEphemeris(int);
+    method public boolean hasAlmanacData(int);
+    method public boolean hasEphemerisData(int);
     method public boolean usedInFix(int);
     field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
     field public static final int CONSTELLATION_GALILEO = 6; // 0x6
@@ -19323,15 +19338,15 @@
     field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
   }
 
-  public abstract class GnssStatusCallback {
-    ctor public GnssStatusCallback();
+  public static abstract class GnssStatus.Callback {
+    ctor public GnssStatus.Callback();
     method public void onFirstFix(int);
     method public void onSatelliteStatusChanged(android.location.GnssStatus);
     method public void onStarted();
     method public void onStopped();
   }
 
-  public final class GpsSatellite {
+  public final deprecated class GpsSatellite {
     method public float getAzimuth();
     method public float getElevation();
     method public int getPrn();
@@ -19341,7 +19356,7 @@
     method public boolean usedInFix();
   }
 
-  public final class GpsStatus {
+  public final deprecated class GpsStatus {
     method public int getMaxSatellites();
     method public java.lang.Iterable<android.location.GpsSatellite> getSatellites();
     method public int getTimeToFirstFix();
@@ -19351,11 +19366,11 @@
     field public static final int GPS_EVENT_STOPPED = 2; // 0x2
   }
 
-  public static abstract interface GpsStatus.Listener {
+  public static abstract deprecated interface GpsStatus.Listener {
     method public abstract void onGpsStatusChanged(int);
   }
 
-  public static abstract interface GpsStatus.NmeaListener {
+  public static abstract deprecated interface GpsStatus.NmeaListener {
     method public abstract void onNmeaReceived(long, java.lang.String);
   }
 
@@ -19417,8 +19432,8 @@
   public class LocationManager {
     method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener);
     method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public boolean addNmeaListener(android.location.GnssNmeaListener);
-    method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+    method public boolean addNmeaListener(android.location.OnNmeaMessageListener);
+    method public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
     method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
     method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
     method public void clearTestProviderEnabled(java.lang.String);
@@ -19434,13 +19449,13 @@
     method public boolean isProviderEnabled(java.lang.String);
     method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
     method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
-    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
-    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
-    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
-    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
     method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener);
     method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public void removeNmeaListener(android.location.GnssNmeaListener);
+    method public void removeNmeaListener(android.location.OnNmeaMessageListener);
     method public void removeProximityAlert(android.app.PendingIntent);
     method public void removeTestProvider(java.lang.String);
     method public void removeUpdates(android.location.LocationListener);
@@ -19459,8 +19474,8 @@
     method public void setTestProviderLocation(java.lang.String, android.location.Location);
     method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
     method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
-    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
-    method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+    method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
     field public static final java.lang.String GPS_PROVIDER = "gps";
     field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
     field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -19489,6 +19504,10 @@
     field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
   }
 
+  public abstract interface OnNmeaMessageListener {
+    method public abstract void onNmeaMessage(java.lang.String, long);
+  }
+
   public abstract class SettingInjectorService extends android.app.Service {
     ctor public SettingInjectorService(java.lang.String);
     method public final android.os.IBinder onBind(android.content.Intent);
@@ -34692,6 +34711,7 @@
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onInterruptionFilterChanged(int);
     method public void onListenerConnected();
+    method public void onListenerDisconnected();
     method public void onListenerHintsChanged(int);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
@@ -50029,6 +50049,9 @@
     method public int compareTo(java.lang.Boolean);
     method public static boolean getBoolean(java.lang.String);
     method public static int hashCode(boolean);
+    method public static boolean logicalAnd(boolean, boolean);
+    method public static boolean logicalOr(boolean, boolean);
+    method public static boolean logicalXor(boolean, boolean);
     method public static boolean parseBoolean(java.lang.String);
     method public static java.lang.String toString(boolean);
     method public static java.lang.Boolean valueOf(boolean);
@@ -50992,6 +51015,8 @@
     method public static float abs(float);
     method public static double abs(double);
     method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
     method public static double asin(double);
     method public static double atan(double);
     method public static double atan2(double, double);
@@ -51001,12 +51026,20 @@
     method public static float copySign(float, float);
     method public static double cos(double);
     method public static double cosh(double);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
     method public static double exp(double);
     method public static double expm1(double);
     method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static long floorMod(long, long);
     method public static int getExponent(float);
     method public static int getExponent(double);
     method public static double hypot(double, double);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
     method public static double log(double);
     method public static double log10(double);
     method public static double log1p(double);
@@ -51018,8 +51051,14 @@
     method public static long min(long, long);
     method public static float min(float, float);
     method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
     method public static double nextAfter(double, double);
     method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
@@ -51034,9 +51073,12 @@
     method public static double sin(double);
     method public static double sinh(double);
     method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
     method public static double tan(double);
     method public static double tanh(double);
     method public static double toDegrees(double);
+    method public static int toIntExact(long);
     method public static double toRadians(double);
     method public static double ulp(double);
     method public static float ulp(float);
@@ -51320,6 +51362,8 @@
     method public static float abs(float);
     method public static double abs(double);
     method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
     method public static double asin(double);
     method public static double atan(double);
     method public static double atan2(double, double);
@@ -51332,6 +51376,10 @@
     method public static double exp(double);
     method public static double expm1(double);
     method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static long floorMod(long, long);
     method public static int getExponent(float);
     method public static int getExponent(double);
     method public static double hypot(double, double);
@@ -51346,8 +51394,12 @@
     method public static long min(long, long);
     method public static float min(float, float);
     method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
     method public static double nextAfter(double, double);
     method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
@@ -51362,9 +51414,12 @@
     method public static double sin(double);
     method public static double sinh(double);
     method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
     method public static double tan(double);
     method public static double tanh(double);
     method public static double toDegrees(double);
+    method public static int toIntExact(long);
     method public static double toRadians(double);
     method public static double ulp(double);
     method public static float ulp(float);
@@ -57412,6 +57467,14 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelPrefix(T[], java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(T[], int, int, java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(long[], java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(long[], int, int, java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(double[], java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(double[], int, int, java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(int[], java.util.function.IntBinaryOperator);
+    method public static void parallelPrefix(int[], int, int, java.util.function.IntBinaryOperator);
     method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
     method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
     method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
diff --git a/api/removed.txt b/api/removed.txt
index 3f16bca..8c6abdc 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -84,6 +84,67 @@
 
 }
 
+package android.location {
+
+  public final class GnssMeasurement implements android.os.Parcelable {
+    field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+  }
+
+  public final class GnssMeasurementsEvent implements android.os.Parcelable {
+    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
+  }
+
+  public final class GnssNavigationMessageEvent implements android.os.Parcelable {
+    ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
+    method public int describeContents();
+    method public android.location.GnssNavigationMessage getNavigationMessage();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
+    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
+  }
+
+  public static abstract class GnssNavigationMessageEvent.Callback {
+    ctor public GnssNavigationMessageEvent.Callback();
+    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
+    method public void onStatusChanged(int);
+  }
+
+  public abstract interface GnssNmeaListener {
+    method public abstract void onNmeaReceived(long, java.lang.String);
+  }
+
+  public final class GnssStatus {
+    method public int getNumSatellites();
+    method public boolean hasAlmanac(int);
+    method public boolean hasEphemeris(int);
+  }
+
+  public abstract class GnssStatusCallback {
+    ctor public GnssStatusCallback();
+    method public void onFirstFix(int);
+    method public void onSatelliteStatusChanged(android.location.GnssStatus);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public class LocationManager {
+    method public boolean addNmeaListener(android.location.GnssNmeaListener);
+    method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+    method public void removeNmeaListener(android.location.GnssNmeaListener);
+    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+    method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index e73287e..039b9ad 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5048,6 +5048,7 @@
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
     field public static final int DEFAULT_SOUND = 1; // 0x1
     field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
     field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
     field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
@@ -5056,12 +5057,14 @@
     field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
     field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
     field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
     field public static final java.lang.String EXTRA_PEOPLE = "android.people";
     field public static final java.lang.String EXTRA_PICTURE = "android.picture";
     field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
     field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
     field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
     field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
     field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
     field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
     field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -5070,6 +5073,7 @@
     field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
     field public static final java.lang.String EXTRA_TEXT = "android.text";
     field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
     field public static final java.lang.String EXTRA_TITLE = "android.title";
     field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
@@ -5309,6 +5313,32 @@
     method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
   }
 
+  public static class Notification.MessagingStyle extends android.app.Notification.Style {
+    ctor public Notification.MessagingStyle(java.lang.CharSequence);
+    method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message);
+    method public boolean getAllowGeneratedReplies();
+    method public java.lang.CharSequence getConversationTitle();
+    method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages();
+    method public java.lang.CharSequence getUserDisplayName();
+    method public android.app.Notification.MessagingStyle setAllowGeneratedReplies(boolean);
+    method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+    ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public int describeContents();
+    method public java.lang.String getDataMimeType();
+    method public android.net.Uri getDataUri();
+    method public java.lang.CharSequence getSender();
+    method public java.lang.CharSequence getText();
+    method public long getTimestamp();
+    method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
+  }
+
   public static abstract class Notification.Style {
     ctor public Notification.Style();
     method public android.app.Notification build();
@@ -7971,8 +8001,6 @@
     method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
-    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
-    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
@@ -20381,7 +20409,7 @@
     field public static final int ADR_STATE_VALID = 1; // 0x1
     field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
     field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
-    field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+    field public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2; // 0x2
     field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
     field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
     field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
@@ -20401,21 +20429,20 @@
   }
 
   public final class GnssMeasurementsEvent implements android.os.Parcelable {
-    ctor public GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]);
     method public int describeContents();
     method public android.location.GnssClock getClock();
     method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
-    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
-    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
-    field public static final int STATUS_READY = 1; // 0x1
   }
 
   public static abstract class GnssMeasurementsEvent.Callback {
     ctor public GnssMeasurementsEvent.Callback();
     method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
     method public void onStatusChanged(int);
+    field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
   }
 
   public final class GnssNavigationMessage implements android.os.Parcelable {
@@ -20443,36 +20470,24 @@
     field public static final int TYPE_UNKNOWN = 0; // 0x0
   }
 
-  public final class GnssNavigationMessageEvent implements android.os.Parcelable {
-    ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
-    method public int describeContents();
-    method public android.location.GnssNavigationMessage getNavigationMessage();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
-    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+  public static abstract class GnssNavigationMessage.Callback {
+    ctor public GnssNavigationMessage.Callback();
+    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessage);
+    method public void onStatusChanged(int);
+    field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
     field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
     field public static final int STATUS_READY = 1; // 0x1
   }
 
-  public static abstract class GnssNavigationMessageEvent.Callback {
-    ctor public GnssNavigationMessageEvent.Callback();
-    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
-    method public void onStatusChanged(int);
-  }
-
-  public abstract interface GnssNmeaListener {
-    method public abstract void onNmeaReceived(long, java.lang.String);
-  }
-
   public final class GnssStatus {
     method public float getAzimuthDegrees(int);
     method public float getCn0DbHz(int);
     method public int getConstellationType(int);
     method public float getElevationDegrees(int);
-    method public int getNumSatellites();
+    method public int getSatelliteCount();
     method public int getSvid(int);
-    method public boolean hasAlmanac(int);
-    method public boolean hasEphemeris(int);
+    method public boolean hasAlmanacData(int);
+    method public boolean hasEphemerisData(int);
     method public boolean usedInFix(int);
     field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
     field public static final int CONSTELLATION_GALILEO = 6; // 0x6
@@ -20483,8 +20498,8 @@
     field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
   }
 
-  public abstract class GnssStatusCallback {
-    ctor public GnssStatusCallback();
+  public static abstract class GnssStatus.Callback {
+    ctor public GnssStatus.Callback();
     method public void onFirstFix(int);
     method public void onSatelliteStatusChanged(android.location.GnssStatus);
     method public void onStarted();
@@ -20716,7 +20731,7 @@
     method public abstract void onStatusChanged(int);
   }
 
-  public final class GpsSatellite {
+  public final deprecated class GpsSatellite {
     method public float getAzimuth();
     method public float getElevation();
     method public int getPrn();
@@ -20726,7 +20741,7 @@
     method public boolean usedInFix();
   }
 
-  public final class GpsStatus {
+  public final deprecated class GpsStatus {
     method public int getMaxSatellites();
     method public java.lang.Iterable<android.location.GpsSatellite> getSatellites();
     method public int getTimeToFirstFix();
@@ -20736,11 +20751,11 @@
     field public static final int GPS_EVENT_STOPPED = 2; // 0x2
   }
 
-  public static abstract interface GpsStatus.Listener {
+  public static abstract deprecated interface GpsStatus.Listener {
     method public abstract void onGpsStatusChanged(int);
   }
 
-  public static abstract interface GpsStatus.NmeaListener {
+  public static abstract deprecated interface GpsStatus.NmeaListener {
     method public abstract void onNmeaReceived(long, java.lang.String);
   }
 
@@ -20824,8 +20839,8 @@
     method public deprecated boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
     method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener);
     method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public boolean addNmeaListener(android.location.GnssNmeaListener);
-    method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+    method public boolean addNmeaListener(android.location.OnNmeaMessageListener);
+    method public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
     method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
     method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
     method public void clearTestProviderEnabled(java.lang.String);
@@ -20841,15 +20856,15 @@
     method public boolean isProviderEnabled(java.lang.String);
     method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
     method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
-    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
-    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
-    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
-    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
     method public deprecated void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
     method public deprecated void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
     method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener);
     method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public void removeNmeaListener(android.location.GnssNmeaListener);
+    method public void removeNmeaListener(android.location.OnNmeaMessageListener);
     method public void removeProximityAlert(android.app.PendingIntent);
     method public void removeTestProvider(java.lang.String);
     method public void removeUpdates(android.location.LocationListener);
@@ -20870,8 +20885,8 @@
     method public void setTestProviderLocation(java.lang.String, android.location.Location);
     method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
     method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
-    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
-    method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+    method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
     field public static final java.lang.String GPS_PROVIDER = "gps";
     field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
     field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -20934,6 +20949,10 @@
     field public static final int POWER_NONE = 200; // 0xc8
   }
 
+  public abstract interface OnNmeaMessageListener {
+    method public abstract void onNmeaMessage(java.lang.String, long);
+  }
+
   public abstract class SettingInjectorService extends android.app.Service {
     ctor public SettingInjectorService(java.lang.String);
     method public final android.os.IBinder onBind(android.content.Intent);
@@ -37158,6 +37177,7 @@
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onInterruptionFilterChanged(int);
     method public void onListenerConnected();
+    method public void onListenerDisconnected();
     method public void onListenerHintsChanged(int);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
@@ -53126,6 +53146,9 @@
     method public int compareTo(java.lang.Boolean);
     method public static boolean getBoolean(java.lang.String);
     method public static int hashCode(boolean);
+    method public static boolean logicalAnd(boolean, boolean);
+    method public static boolean logicalOr(boolean, boolean);
+    method public static boolean logicalXor(boolean, boolean);
     method public static boolean parseBoolean(java.lang.String);
     method public static java.lang.String toString(boolean);
     method public static java.lang.Boolean valueOf(boolean);
@@ -54089,6 +54112,8 @@
     method public static float abs(float);
     method public static double abs(double);
     method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
     method public static double asin(double);
     method public static double atan(double);
     method public static double atan2(double, double);
@@ -54098,12 +54123,20 @@
     method public static float copySign(float, float);
     method public static double cos(double);
     method public static double cosh(double);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
     method public static double exp(double);
     method public static double expm1(double);
     method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static long floorMod(long, long);
     method public static int getExponent(float);
     method public static int getExponent(double);
     method public static double hypot(double, double);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
     method public static double log(double);
     method public static double log10(double);
     method public static double log1p(double);
@@ -54115,8 +54148,14 @@
     method public static long min(long, long);
     method public static float min(float, float);
     method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
     method public static double nextAfter(double, double);
     method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
@@ -54131,9 +54170,12 @@
     method public static double sin(double);
     method public static double sinh(double);
     method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
     method public static double tan(double);
     method public static double tanh(double);
     method public static double toDegrees(double);
+    method public static int toIntExact(long);
     method public static double toRadians(double);
     method public static double ulp(double);
     method public static float ulp(float);
@@ -54417,6 +54459,8 @@
     method public static float abs(float);
     method public static double abs(double);
     method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
     method public static double asin(double);
     method public static double atan(double);
     method public static double atan2(double, double);
@@ -54429,6 +54473,10 @@
     method public static double exp(double);
     method public static double expm1(double);
     method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static long floorMod(long, long);
     method public static int getExponent(float);
     method public static int getExponent(double);
     method public static double hypot(double, double);
@@ -54443,8 +54491,12 @@
     method public static long min(long, long);
     method public static float min(float, float);
     method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
     method public static double nextAfter(double, double);
     method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
@@ -54459,9 +54511,12 @@
     method public static double sin(double);
     method public static double sinh(double);
     method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
     method public static double tan(double);
     method public static double tanh(double);
     method public static double toDegrees(double);
+    method public static int toIntExact(long);
     method public static double toRadians(double);
     method public static double ulp(double);
     method public static float ulp(float);
@@ -60509,6 +60564,14 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelPrefix(T[], java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(T[], int, int, java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(long[], java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(long[], int, int, java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(double[], java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(double[], int, int, java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(int[], java.util.function.IntBinaryOperator);
+    method public static void parallelPrefix(int[], int, int, java.util.function.IntBinaryOperator);
     method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
     method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
     method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 03cf8b0..95734c1 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -82,6 +82,67 @@
 
 }
 
+package android.location {
+
+  public final class GnssMeasurement implements android.os.Parcelable {
+    field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+  }
+
+  public final class GnssMeasurementsEvent implements android.os.Parcelable {
+    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
+  }
+
+  public final class GnssNavigationMessageEvent implements android.os.Parcelable {
+    ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
+    method public int describeContents();
+    method public android.location.GnssNavigationMessage getNavigationMessage();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
+    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
+  }
+
+  public static abstract class GnssNavigationMessageEvent.Callback {
+    ctor public GnssNavigationMessageEvent.Callback();
+    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
+    method public void onStatusChanged(int);
+  }
+
+  public abstract interface GnssNmeaListener {
+    method public abstract void onNmeaReceived(long, java.lang.String);
+  }
+
+  public final class GnssStatus {
+    method public int getNumSatellites();
+    method public boolean hasAlmanac(int);
+    method public boolean hasEphemeris(int);
+  }
+
+  public abstract class GnssStatusCallback {
+    ctor public GnssStatusCallback();
+    method public void onFirstFix(int);
+    method public void onSatelliteStatusChanged(android.location.GnssStatus);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public class LocationManager {
+    method public boolean addNmeaListener(android.location.GnssNmeaListener);
+    method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+    method public void removeNmeaListener(android.location.GnssNmeaListener);
+    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+    method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index a4408be..3febda1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4915,6 +4915,7 @@
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
     field public static final int DEFAULT_SOUND = 1; // 0x1
     field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
     field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
     field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
@@ -4923,12 +4924,14 @@
     field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
     field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
     field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
     field public static final java.lang.String EXTRA_PEOPLE = "android.people";
     field public static final java.lang.String EXTRA_PICTURE = "android.picture";
     field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
     field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
     field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
     field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
     field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
     field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
     field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -4937,6 +4940,7 @@
     field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
     field public static final java.lang.String EXTRA_TEXT = "android.text";
     field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
     field public static final java.lang.String EXTRA_TITLE = "android.title";
     field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
@@ -5176,6 +5180,32 @@
     method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
   }
 
+  public static class Notification.MessagingStyle extends android.app.Notification.Style {
+    ctor public Notification.MessagingStyle(java.lang.CharSequence);
+    method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message);
+    method public boolean getAllowGeneratedReplies();
+    method public java.lang.CharSequence getConversationTitle();
+    method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages();
+    method public java.lang.CharSequence getUserDisplayName();
+    method public android.app.Notification.MessagingStyle setAllowGeneratedReplies(boolean);
+    method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+    ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public int describeContents();
+    method public java.lang.String getDataMimeType();
+    method public android.net.Uri getDataUri();
+    method public java.lang.CharSequence getSender();
+    method public java.lang.CharSequence getText();
+    method public long getTimestamp();
+    method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
+  }
+
   public static abstract class Notification.Style {
     ctor public Notification.Style();
     method public android.app.Notification build();
@@ -7677,8 +7707,6 @@
     method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
-    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
-    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
@@ -19276,7 +19304,7 @@
     field public static final int ADR_STATE_VALID = 1; // 0x1
     field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
     field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
-    field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+    field public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2; // 0x2
     field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
     field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
     field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
@@ -19302,15 +19330,15 @@
     method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
-    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
-    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
-    field public static final int STATUS_READY = 1; // 0x1
   }
 
   public static abstract class GnssMeasurementsEvent.Callback {
     ctor public GnssMeasurementsEvent.Callback();
     method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
     method public void onStatusChanged(int);
+    field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
   }
 
   public final class GnssNavigationMessage implements android.os.Parcelable {
@@ -19347,36 +19375,24 @@
     field public static final int TYPE_UNKNOWN = 0; // 0x0
   }
 
-  public final class GnssNavigationMessageEvent implements android.os.Parcelable {
-    ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
-    method public int describeContents();
-    method public android.location.GnssNavigationMessage getNavigationMessage();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
-    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+  public static abstract class GnssNavigationMessage.Callback {
+    ctor public GnssNavigationMessage.Callback();
+    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessage);
+    method public void onStatusChanged(int);
+    field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
     field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
     field public static final int STATUS_READY = 1; // 0x1
   }
 
-  public static abstract class GnssNavigationMessageEvent.Callback {
-    ctor public GnssNavigationMessageEvent.Callback();
-    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
-    method public void onStatusChanged(int);
-  }
-
-  public abstract interface GnssNmeaListener {
-    method public abstract void onNmeaReceived(long, java.lang.String);
-  }
-
   public final class GnssStatus {
     method public float getAzimuthDegrees(int);
     method public float getCn0DbHz(int);
     method public int getConstellationType(int);
     method public float getElevationDegrees(int);
-    method public int getNumSatellites();
+    method public int getSatelliteCount();
     method public int getSvid(int);
-    method public boolean hasAlmanac(int);
-    method public boolean hasEphemeris(int);
+    method public boolean hasAlmanacData(int);
+    method public boolean hasEphemerisData(int);
     method public boolean usedInFix(int);
     field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
     field public static final int CONSTELLATION_GALILEO = 6; // 0x6
@@ -19387,15 +19403,15 @@
     field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
   }
 
-  public abstract class GnssStatusCallback {
-    ctor public GnssStatusCallback();
+  public static abstract class GnssStatus.Callback {
+    ctor public GnssStatus.Callback();
     method public void onFirstFix(int);
     method public void onSatelliteStatusChanged(android.location.GnssStatus);
     method public void onStarted();
     method public void onStopped();
   }
 
-  public final class GpsSatellite {
+  public final deprecated class GpsSatellite {
     method public float getAzimuth();
     method public float getElevation();
     method public int getPrn();
@@ -19405,7 +19421,7 @@
     method public boolean usedInFix();
   }
 
-  public final class GpsStatus {
+  public final deprecated class GpsStatus {
     method public int getMaxSatellites();
     method public java.lang.Iterable<android.location.GpsSatellite> getSatellites();
     method public int getTimeToFirstFix();
@@ -19415,11 +19431,11 @@
     field public static final int GPS_EVENT_STOPPED = 2; // 0x2
   }
 
-  public static abstract interface GpsStatus.Listener {
+  public static abstract deprecated interface GpsStatus.Listener {
     method public abstract void onGpsStatusChanged(int);
   }
 
-  public static abstract interface GpsStatus.NmeaListener {
+  public static abstract deprecated interface GpsStatus.NmeaListener {
     method public abstract void onNmeaReceived(long, java.lang.String);
   }
 
@@ -19481,8 +19497,8 @@
   public class LocationManager {
     method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener);
     method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public boolean addNmeaListener(android.location.GnssNmeaListener);
-    method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+    method public boolean addNmeaListener(android.location.OnNmeaMessageListener);
+    method public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
     method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
     method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
     method public void clearTestProviderEnabled(java.lang.String);
@@ -19499,13 +19515,13 @@
     method public boolean isProviderEnabled(java.lang.String);
     method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
     method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
-    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
-    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
-    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
-    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
     method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener);
     method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public void removeNmeaListener(android.location.GnssNmeaListener);
+    method public void removeNmeaListener(android.location.OnNmeaMessageListener);
     method public void removeProximityAlert(android.app.PendingIntent);
     method public void removeTestProvider(java.lang.String);
     method public void removeUpdates(android.location.LocationListener);
@@ -19524,8 +19540,8 @@
     method public void setTestProviderLocation(java.lang.String, android.location.Location);
     method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
     method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
-    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
-    method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
+    method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
     field public static final java.lang.String GPS_PROVIDER = "gps";
     field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
     field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -19554,6 +19570,10 @@
     field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
   }
 
+  public abstract interface OnNmeaMessageListener {
+    method public abstract void onNmeaMessage(java.lang.String, long);
+  }
+
   public abstract class SettingInjectorService extends android.app.Service {
     ctor public SettingInjectorService(java.lang.String);
     method public final android.os.IBinder onBind(android.content.Intent);
@@ -34764,6 +34784,7 @@
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onInterruptionFilterChanged(int);
     method public void onListenerConnected();
+    method public void onListenerDisconnected();
     method public void onListenerHintsChanged(int);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
@@ -50104,6 +50125,9 @@
     method public int compareTo(java.lang.Boolean);
     method public static boolean getBoolean(java.lang.String);
     method public static int hashCode(boolean);
+    method public static boolean logicalAnd(boolean, boolean);
+    method public static boolean logicalOr(boolean, boolean);
+    method public static boolean logicalXor(boolean, boolean);
     method public static boolean parseBoolean(java.lang.String);
     method public static java.lang.String toString(boolean);
     method public static java.lang.Boolean valueOf(boolean);
@@ -51067,6 +51091,8 @@
     method public static float abs(float);
     method public static double abs(double);
     method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
     method public static double asin(double);
     method public static double atan(double);
     method public static double atan2(double, double);
@@ -51076,12 +51102,20 @@
     method public static float copySign(float, float);
     method public static double cos(double);
     method public static double cosh(double);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
     method public static double exp(double);
     method public static double expm1(double);
     method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static long floorMod(long, long);
     method public static int getExponent(float);
     method public static int getExponent(double);
     method public static double hypot(double, double);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
     method public static double log(double);
     method public static double log10(double);
     method public static double log1p(double);
@@ -51093,8 +51127,14 @@
     method public static long min(long, long);
     method public static float min(float, float);
     method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
     method public static double nextAfter(double, double);
     method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
@@ -51109,9 +51149,12 @@
     method public static double sin(double);
     method public static double sinh(double);
     method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
     method public static double tan(double);
     method public static double tanh(double);
     method public static double toDegrees(double);
+    method public static int toIntExact(long);
     method public static double toRadians(double);
     method public static double ulp(double);
     method public static float ulp(float);
@@ -51395,6 +51438,8 @@
     method public static float abs(float);
     method public static double abs(double);
     method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
     method public static double asin(double);
     method public static double atan(double);
     method public static double atan2(double, double);
@@ -51407,6 +51452,10 @@
     method public static double exp(double);
     method public static double expm1(double);
     method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static long floorMod(long, long);
     method public static int getExponent(float);
     method public static int getExponent(double);
     method public static double hypot(double, double);
@@ -51421,8 +51470,12 @@
     method public static long min(long, long);
     method public static float min(float, float);
     method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
     method public static double nextAfter(double, double);
     method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
     method public static double nextUp(double);
     method public static float nextUp(float);
     method public static double pow(double, double);
@@ -51437,9 +51490,12 @@
     method public static double sin(double);
     method public static double sinh(double);
     method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
     method public static double tan(double);
     method public static double tanh(double);
     method public static double toDegrees(double);
+    method public static int toIntExact(long);
     method public static double toRadians(double);
     method public static double ulp(double);
     method public static float ulp(float);
@@ -57487,6 +57543,14 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelPrefix(T[], java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(T[], int, int, java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(long[], java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(long[], int, int, java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(double[], java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(double[], int, int, java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(int[], java.util.function.IntBinaryOperator);
+    method public static void parallelPrefix(int[], int, int, java.util.function.IntBinaryOperator);
     method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
     method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
     method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 3f16bca..8c6abdc 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -84,6 +84,67 @@
 
 }
 
+package android.location {
+
+  public final class GnssMeasurement implements android.os.Parcelable {
+    field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+  }
+
+  public final class GnssMeasurementsEvent implements android.os.Parcelable {
+    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
+  }
+
+  public final class GnssNavigationMessageEvent implements android.os.Parcelable {
+    ctor public GnssNavigationMessageEvent(android.location.GnssNavigationMessage);
+    method public int describeContents();
+    method public android.location.GnssNavigationMessage getNavigationMessage();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
+    field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
+    field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+    field public static final int STATUS_READY = 1; // 0x1
+  }
+
+  public static abstract class GnssNavigationMessageEvent.Callback {
+    ctor public GnssNavigationMessageEvent.Callback();
+    method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessageEvent);
+    method public void onStatusChanged(int);
+  }
+
+  public abstract interface GnssNmeaListener {
+    method public abstract void onNmeaReceived(long, java.lang.String);
+  }
+
+  public final class GnssStatus {
+    method public int getNumSatellites();
+    method public boolean hasAlmanac(int);
+    method public boolean hasEphemeris(int);
+  }
+
+  public abstract class GnssStatusCallback {
+    ctor public GnssStatusCallback();
+    method public void onFirstFix(int);
+    method public void onSatelliteStatusChanged(android.location.GnssStatus);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public class LocationManager {
+    method public boolean addNmeaListener(android.location.GnssNmeaListener);
+    method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+    method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
+    method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler);
+    method public void removeNmeaListener(android.location.GnssNmeaListener);
+    method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
+    method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 0e674c8..d527ad7 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -74,6 +74,8 @@
             runGetPrimaryStorageUuid();
         } else if ("set-force-adoptable".equals(op)) {
             runSetForceAdoptable();
+        } else if ("set-sdcardfs".equals(op)) {
+            runSetSdcardfs();
         } else if ("partition".equals(op)) {
             runPartition();
         } else if ("mount".equals(op)) {
@@ -141,6 +143,22 @@
                 StorageManager.DEBUG_FORCE_ADOPTABLE);
     }
 
+    public void runSetSdcardfs() throws RemoteException {
+        final int mask = StorageManager.DEBUG_SDCARDFS_FORCE_ON
+                | StorageManager.DEBUG_SDCARDFS_FORCE_OFF;
+        switch (nextArg()) {
+            case "on":
+                mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_ON, mask);
+                break;
+            case "off":
+                mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_OFF, mask);
+                break;
+            case "default":
+                mSm.setDebugFlags(0, mask);
+                break;
+        }
+    }
+
     public void runSetEmulateFbe() throws RemoteException {
         final boolean emulateFbe = Boolean.parseBoolean(nextArg());
         mSm.setDebugFlags(emulateFbe ? StorageManager.DEBUG_EMULATE_FBE : 0,
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index bf823f8..56728ad 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -600,11 +600,16 @@
      * Dispatch a gesture to the touch screen. Any gestures currently in progress, whether from
      * the user, this service, or another service, will be cancelled.
      * <p>
+     * The gesture will be dispatched as if it were performed directly on the screen by a user, so
+     * the events may be affected by features such as magnification and explore by touch.
+     * </p>
+     * <p>
      * <strong>Note:</strong> In order to dispatch gestures, your service
      * must declare the capability by setting the
      * {@link android.R.styleable#AccessibilityService_canPerformGestures}
      * property in its meta-data. For more information, see
      * {@link #SERVICE_META_DATA}.
+     * </p>
      *
      * @param gesture The gesture to dispatch
      * @param callback The object to call back when the status of the gesture is known. If
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 14c4fc6..96e1eaa 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1526,7 +1526,7 @@
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case CREATE_SERVICE:
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                     handleCreateService((CreateServiceData)msg.obj);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
@@ -1541,7 +1541,7 @@
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case SERVICE_ARGS:
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
                     handleServiceArgs((ServiceArgsData)msg.obj);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index fa67529..496ca6f 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -40,4 +40,9 @@
      * Called when we launched an activity that we forced to be resizable.
      */
     void onActivityForcedResizable(String packageName, int taskId);
+
+    /**
+     * Callen when we launched an activity that is dismissed the docked stack.
+     */
+    void onActivityDismissingDockedStack();
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 2e4a8c6..faefc9d 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -904,6 +904,34 @@
     public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
 
     /**
+     * {@link #extras} key: the username to be displayed for all messages sent by the user including
+     * direct replies
+     * {@link android.app.Notification.MessagingStyle} notification.
+     */
+    public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+
+    /**
+     * {@link #extras} key: a boolean describing whether the platform should automatically
+     * generate possible replies to
+     * {@link android.app.Notification.MessagingStyle.Message} objects provided by a
+     * {@link android.app.Notification.MessagingStyle} notification.
+     */
+    public static final String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
+
+    /**
+     * {@link #extras} key: a {@link String} to be displayed as the title to a thread represented by
+     * a {@link android.app.Notification.MessagingStyle}
+     */
+    public static final String EXTRA_THREAD_TITLE = "android.threadTitle";
+
+    /**
+     * {@link #extras} key: an array of {@link android.app.Notification.MessagingStyle.Message}
+     * bundles provided by a
+     * {@link android.app.Notification.MessagingStyle} notification.
+     */
+    public static final String EXTRA_MESSAGES = "android.messages";
+
+    /**
      * {@link #extras} key: the user that built the notification.
      *
      * @hide
@@ -3560,7 +3588,8 @@
         private static Class<? extends Style> getNotificationStyleClass(String templateClass) {
             Class<? extends Style>[] classes = new Class[] {
                     BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
-                    DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class };
+                    DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
+                    MessagingStyle.class };
             for (Class<? extends Style> innerClass : classes) {
                 if (templateClass.equals(innerClass.getName())) {
                     return innerClass;
@@ -4157,6 +4186,350 @@
     }
 
     /**
+     * Helper class for generating large-format notifications that include multiple back-and-forth
+     * messages of varying types between any number of people.
+     *
+     * <br>
+     * If the platform does not provide large-format notifications, this method has no effect. The
+     * user will always see the normal notification view.
+     * <br>
+     * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like
+     * so:
+     * <pre class="prettyprint">
+     *
+     * Notification noti = new Notification.Builder()
+     *     .setContentTitle(&quot;2 new messages wtih &quot; + sender.toString())
+     *     .setContentText(subject)
+     *     .setSmallIcon(R.drawable.new_message)
+     *     .setLargeIcon(aBitmap)
+     *     .setStyle(new Notification.MessagingStyle(resources.getString(R.string.reply_name))
+     *         .addMessage(messages[0].getText(), messages[0].getTime(), messages[0].getSender())
+     *         .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getSender()))
+     *     .build();
+     * </pre>
+     */
+    public static class MessagingStyle extends Style {
+
+        /**
+         * The maximum number of messages that will be retained in the Notification itself (the
+         * number displayed is up to the platform).
+         */
+        public static final int MAXIMUM_RETAINED_MESSAGES = 25;
+
+        CharSequence mUserDisplayName;
+        CharSequence mConversationTitle;
+        boolean mAllowGeneratedReplies = true;
+        ArrayList<Message> mMessages = new ArrayList<>();
+
+        MessagingStyle() {
+        }
+
+        /**
+         * @param userDisplayName the name to be displayed for any replies sent by the user before the
+         * posting app reposts the notification with those messages after they've been actually
+         * sent and in previous messages sent by the user added in
+         * {@link #addMessage(Notification.MessagingStyle.Message)}
+         */
+        public MessagingStyle(CharSequence userDisplayName) {
+            mUserDisplayName = userDisplayName;
+        }
+
+        /**
+         * Returns the name to be displayed for any replies sent by the user
+         */
+        public CharSequence getUserDisplayName() {
+            return mUserDisplayName;
+        }
+
+        /**
+         * Set whether the platform should automatically generate possible replies from messages.
+         * @param allowGeneratedReplies {@code true} to allow generated replies, {@code false}
+         * otherwise
+         * @return this object for method chaining
+         * The default value is {@code true}
+         */
+        public MessagingStyle setAllowGeneratedReplies(boolean allowGeneratedReplies) {
+            mAllowGeneratedReplies = allowGeneratedReplies;
+            return this;
+        }
+
+        /**
+         * Return whether the platform should automatically generate possible replies from messages.
+         */
+        public boolean getAllowGeneratedReplies() {
+            return mAllowGeneratedReplies;
+        }
+
+        /**
+         * Sets the title to be displayed on this conversation. This should only be used for
+         * group messaging and left unset for one-on-one conversations.
+         * @param conversationTitle
+         * @return this object for method chaining.
+         */
+        public MessagingStyle setConversationTitle(CharSequence conversationTitle) {
+            mConversationTitle = conversationTitle;
+            return this;
+        }
+
+        /**
+         * Return the title to be displayed on this conversation. Can be <code>null</code> and
+         * should be for one-on-one conversations
+         */
+        public CharSequence getConversationTitle() {
+            return mConversationTitle;
+        }
+
+        /**
+         * Adds a message for display by this notification. Convenience call for a simple
+         * {@link Message} in {@link #addMessage(Notification.MessagingStyle.Message)}.
+         * @param text A {@link CharSequence} to be displayed as the message content
+         * @param timestamp Time at which the message arrived
+         * @param sender A {@link CharSequence} to be used for displaying the name of the
+         * sender. Should be <code>null</code> for messages by the current user, in which case
+         * the platform will insert {@link #getUserDisplayName()}.
+         * Should be unique amongst all individuals in the conversation, and should be
+         * consistent during re-posts of the notification.
+         *
+         * @see Message#Message(CharSequence, long, CharSequence)
+         *
+         * @return this object for method chaining
+         */
+        public MessagingStyle addMessage(CharSequence text, long timestamp, CharSequence sender) {
+            mMessages.add(new Message(text, timestamp, sender));
+            if (mMessages.size() > MAXIMUM_RETAINED_MESSAGES) {
+                mMessages.remove(0);
+            }
+            return this;
+        }
+
+        /**
+         * Adds a {@link Message} for display in this notification.
+         * @param message The {@link Message} to be displayed
+         * @return this object for method chaining
+         */
+        public MessagingStyle addMessage(Message message) {
+            mMessages.add(message);
+            if (mMessages.size() > MAXIMUM_RETAINED_MESSAGES) {
+                mMessages.remove(0);
+            }
+            return this;
+        }
+
+        /**
+         * Gets the list of {@code Message} objects that represent the notification
+         */
+        public List<Message> getMessages() {
+            return mMessages;
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void addExtras(Bundle extras) {
+            super.addExtras(extras);
+            if (mUserDisplayName != null) {
+                extras.putCharSequence(EXTRA_SELF_DISPLAY_NAME, mUserDisplayName);
+            }
+            if (mConversationTitle != null) {
+                extras.putCharSequence(EXTRA_THREAD_TITLE, mConversationTitle);
+            }
+            extras.putBoolean(EXTRA_ALLOW_GENERATED_REPLIES, mAllowGeneratedReplies);
+            if (!mMessages.isEmpty()) {
+                extras.putParcelableArrayList(EXTRA_MESSAGES, mMessages);
+            }
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        protected void restoreFromExtras(Bundle extras) {
+            super.restoreFromExtras(extras);
+
+            mMessages.clear();
+            mUserDisplayName = extras.getString(EXTRA_SELF_DISPLAY_NAME);
+            mConversationTitle = extras.getString(EXTRA_THREAD_TITLE);
+            mAllowGeneratedReplies = extras.getBoolean(EXTRA_ALLOW_GENERATED_REPLIES,
+                    mAllowGeneratedReplies);
+            List<Message> messages = extras.getParcelableArrayList(EXTRA_MESSAGES);
+            if (messages != null) {
+                mMessages.addAll(messages);
+            }
+        }
+
+        /**
+         * @hide
+         */
+        public RemoteViews makeBigContentView() {
+            // TODO handset to write implementation
+            RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource());
+
+            return contentView;
+        }
+
+        public static final class Message implements Parcelable {
+
+            private final CharSequence mText;
+            private final long mTimestamp;
+            private final CharSequence mSender;
+
+            private String mDataMimeType;
+            private Uri mDataUri;
+
+            /**
+             * Constructor
+             * @param text A {@link CharSequence} to be displayed as the message content
+             * @param timestamp Time at which the message arrived
+             * @param sender A {@link CharSequence} to be used for displaying the name of the
+             * sender. Should be <code>null</code> for messages by the current user, in which case
+             * the platform will insert {@link MessagingStyle#getUserDisplayName()}.
+             * Should be unique amongst all individuals in the conversation, and should be
+             * consistent during re-posts of the notification.
+             */
+            public Message(CharSequence text, long timestamp, CharSequence sender){
+                mText = text;
+                mTimestamp = timestamp;
+                mSender = sender;
+            }
+
+            /**
+             * Sets a binary blob of data and an associated MIME type for a message. In the case
+             * where the platform doesn't support the MIME type, the original text provided in the
+             * constructor will be used.
+             * @param dataMimeType The MIME type of the content. See
+             * <a href="{@docRoot}notifications/messaging.html"> for the list of supported MIME
+             * types on Android and Android Wear.
+             * @param dataUri The uri containing the content whose type is given by the MIME type.
+             * <p class="note">
+             * <ol>
+             *   <li>Notification Listeners including the System UI need permission to access the
+             *       data the Uri points to. The recommended ways to do this are:</li>
+             *   <li>Store the data in your own ContentProvider, making sure that other apps have
+             *       the correct permission to access your provider. The preferred mechanism for
+             *       providing access is to use per-URI permissions which are temporary and only
+             *       grant access to the receiving application. An easy way to create a
+             *       ContentProvider like this is to use the FileProvider helper class.</li>
+             *   <li>Use the system MediaStore. The MediaStore is primarily aimed at video, audio
+             *       and image MIME types, however beginning with Android 3.0 (API level 11) it can
+             *       also store non-media types (see MediaStore.Files for more info). Files can be
+             *       inserted into the MediaStore using scanFile() after which a content:// style
+             *       Uri suitable for sharing is passed to the provided onScanCompleted() callback.
+             *       Note that once added to the system MediaStore the content is accessible to any
+             *       app on the device.</li>
+             * </ol>
+             * @return this object for method chaining
+             */
+            public Message setData(String dataMimeType, Uri dataUri) {
+                mDataMimeType = dataMimeType;
+                mDataUri = dataUri;
+                return this;
+            }
+
+            private Message(Parcel in) {
+                if (in.readInt() != 0) {
+                    mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+                } else {
+                    mText = null;
+                }
+                mTimestamp = in.readLong();
+                if (in.readInt() != 0) {
+                    mSender = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+                } else {
+                    mSender = null;
+                }
+                if (in.readInt() != 0) {
+                    mDataMimeType = in.readString();
+                }
+                if (in.readInt() != 0) {
+                    mDataUri = in.readParcelable(Uri.class.getClassLoader());
+                }
+            }
+
+            /**
+             * Get the text to be used for this message, or the fallback text if a type and content
+             * Uri have been set
+             */
+            public CharSequence getText() {
+                return mText;
+            }
+
+            /**
+             * Get the time at which this message arrived
+             */
+            public long getTimestamp() {
+                return mTimestamp;
+            }
+
+            /**
+             * Get the text used to display the contact's name in the messaging experience
+             */
+            public CharSequence getSender() {
+                return mSender;
+            }
+
+            /**
+             * Get the MIME type of the data pointed to by the Uri
+             */
+            public String getDataMimeType() {
+                return mDataMimeType;
+            }
+
+            /**
+             * Get the the Uri pointing to the content of the message. Can be null, in which case
+             * {@see #getText()} is used.
+             */
+            public Uri getDataUri() {
+                return mDataUri;
+            }
+
+            @Override
+            public int describeContents() {
+                return 0;
+            }
+
+            @Override
+            public void writeToParcel(Parcel out, int flags) {
+                if (mText != null) {
+                    out.writeInt(1);
+                    TextUtils.writeToParcel(mText, out, flags);
+                } else {
+                    out.writeInt(0);
+                }
+                out.writeLong(mTimestamp);
+                if (mSender != null) {
+                    out.writeInt(1);
+                    TextUtils.writeToParcel(mSender, out, flags);
+                } else {
+                    out.writeInt(0);
+                }
+                if (mDataMimeType != null) {
+                    out.writeInt(1);
+                    out.writeString(mDataMimeType);
+                } else {
+                    out.writeInt(0);
+                }
+                if (mDataUri != null) {
+                    out.writeInt(1);
+                    out.writeParcelable(mDataUri, flags);
+                } else {
+                    out.writeInt(0);
+                }
+            }
+
+            public static final Parcelable.Creator<Message> CREATOR =
+                    new Parcelable.Creator<Message>() {
+                        public Message createFromParcel(Parcel in) {
+                            return new Message(in);
+                        }
+                        public Message[] newArray(int size) {
+                            return new Message[size];
+                        }
+                    };
+        }
+    }
+
+    /**
      * Helper class for generating large-format notifications that include a list of (up to 5) strings.
      *
      * Here's how you'd set the <code>InboxStyle</code> on a notification:
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 1b024e2..461d1e0 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -71,6 +71,7 @@
      * and {@link ComponentName#flattenToString()} to convert the extra value
      * to/from {@link ComponentName}.
      * </p>
+     * @hide
      */
     public static final String EXTRA_TARGET_COMPONENT_NAME =
             "android.content.extra.TARGET_COMPONENT_NAME";
@@ -81,6 +82,7 @@
      * <p>
      * Type: long
      * </p>
+     * @hide
      */
     public static final String EXTRA_USER_SERIAL_NUMBER =
             "android.content.extra.USER_SERIAL_NUMBER";
diff --git a/core/java/android/content/pm/FeatureInfo.java b/core/java/android/content/pm/FeatureInfo.java
index 7671f72..9ee6fa2 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -48,6 +48,9 @@
      * <p>
      * If this object represents a feature requested by an app, this is the
      * minimum version of the feature required by the app.
+     * <p>
+     * When a feature version is undefined by a device, it's assumed to be
+     * version 0.
      */
     public int version;
 
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index a762f59..34a9523 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -26,6 +26,7 @@
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.util.Log;
 import android.util.LruCache;
@@ -1311,7 +1312,8 @@
                         operation.mBindArgs.clear();
                     }
                 }
-                operation.mStartTime = System.currentTimeMillis();
+                operation.mStartWallTime = System.currentTimeMillis();
+                operation.mStartTime = SystemClock.uptimeMillis();
                 operation.mKind = kind;
                 operation.mSql = sql;
                 if (bindArgs != null) {
@@ -1376,7 +1378,7 @@
                     Trace.asyncTraceEnd(Trace.TRACE_TAG_DATABASE, operation.getTraceMethodName(),
                             operation.mCookie);
                 }
-                operation.mEndTime = System.currentTimeMillis();
+                operation.mEndTime = SystemClock.uptimeMillis();
                 operation.mFinished = true;
                 return SQLiteDebug.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
                                 operation.mEndTime - operation.mStartTime);
@@ -1454,8 +1456,9 @@
         // marker for us, potentially losing metadata in the process).
         private static final int MAX_TRACE_METHOD_NAME_LEN = 256;
 
-        public long mStartTime;
-        public long mEndTime;
+        public long mStartWallTime; // in System.currentTimeMillis()
+        public long mStartTime; // in SystemClock.uptimeMillis();
+        public long mEndTime; // in SystemClock.uptimeMillis();
         public String mKind;
         public String mSql;
         public ArrayList<Object> mBindArgs;
@@ -1468,7 +1471,7 @@
             if (mFinished) {
                 msg.append(" took ").append(mEndTime - mStartTime).append("ms");
             } else {
-                msg.append(" started ").append(System.currentTimeMillis() - mStartTime)
+                msg.append(" started ").append(System.currentTimeMillis() - mStartWallTime)
                         .append("ms ago");
             }
             msg.append(" - ").append(getStatus());
@@ -1519,7 +1522,7 @@
             //       relatively expensive to create during preloading. This method is only used
             //       when dumping a connection, which is a rare (mainly error) case. So:
             //       DO NOT CACHE.
-            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(mStartTime));
+            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(mStartWallTime));
         }
     }
 }
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index e40ebf7..d39968a 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -115,6 +115,13 @@
      */
     public static final String EXTRA_MAX_CHARGING_VOLTAGE = "max_charging_voltage";
 
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the charge counter present in the battery.
+     * {@hide}
+     */
+     public static final String EXTRA_CHARGE_COUNTER = "charge_counter";
+
     // values for "status" field in the ACTION_BATTERY_CHANGED Intent
     public static final int BATTERY_STATUS_UNKNOWN = 1;
     public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index c3e0f24..b509d76 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -30,6 +30,7 @@
     public int batteryLevel;
     public int batteryVoltage;
     public int batteryTemperature;
+    public int batteryChargeCounter;
     public String batteryTechnology;
 
     public BatteryProperties() {
@@ -47,6 +48,7 @@
         batteryLevel = other.batteryLevel;
         batteryVoltage = other.batteryVoltage;
         batteryTemperature = other.batteryTemperature;
+        batteryChargeCounter = other.batteryChargeCounter;
         batteryTechnology = other.batteryTechnology;
     }
 
@@ -67,6 +69,7 @@
         batteryLevel = p.readInt();
         batteryVoltage = p.readInt();
         batteryTemperature = p.readInt();
+        batteryChargeCounter = p.readInt();
         batteryTechnology = p.readString();
     }
 
@@ -82,6 +85,7 @@
         p.writeInt(batteryLevel);
         p.writeInt(batteryVoltage);
         p.writeInt(batteryTemperature);
+        p.writeInt(batteryChargeCounter);
         p.writeString(batteryTechnology);
     }
 
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f2e316c..ece1228 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -83,6 +83,8 @@
     public static final String PROP_FORCE_ADOPTABLE = "persist.fw.force_adoptable";
     /** {@hide} */
     public static final String PROP_EMULATE_FBE = "persist.sys.emulate_fbe";
+    /** {@hide} */
+    public static final String PROP_SDCARDFS = "persist.sys.sdcardfs";
 
     /** {@hide} */
     public static final String UUID_PRIVATE_INTERNAL = null;
@@ -93,6 +95,10 @@
     public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;
     /** {@hide} */
     public static final int DEBUG_EMULATE_FBE = 1 << 1;
+    /** {@hide} */
+    public static final int DEBUG_SDCARDFS_FORCE_ON = 1 << 2;
+    /** {@hide} */
+    public static final int DEBUG_SDCARDFS_FORCE_OFF = 1 << 3;
 
     // NOTE: keep in sync with installd
     /** {@hide} */
@@ -1178,7 +1184,23 @@
 
     /** {@hide} */
     public static File maybeTranslateEmulatedPathToInternal(File path) {
-        // Disabled now that FUSE has been replaced by sdcardfs
+        final IMountService mountService = IMountService.Stub.asInterface(
+                ServiceManager.getService("mount"));
+        try {
+            final VolumeInfo[] vols = mountService.getVolumes(0);
+            for (VolumeInfo vol : vols) {
+                if ((vol.getType() == VolumeInfo.TYPE_EMULATED
+                        || vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) {
+                    final File internalPath = FileUtils.rewriteAfterRename(vol.getPath(),
+                            vol.getInternalPath(), path);
+                    if (internalPath != null && internalPath.exists()) {
+                        return internalPath;
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
         return path;
     }
 
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index afdd1d4..7325aef 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -69,6 +69,12 @@
  *         &lt;action android:name="android.service.notification.NotificationListenerService" />
  *     &lt;/intent-filter>
  * &lt;/service></pre>
+ *
+ * <p>The service should wait for the {@link #onListenerConnected()} event
+ * before performing any operations. The {@link #requestRebind(ComponentName)}
+ * method is the <i>only</i> one that is safe to call before {@link #onListenerConnected()}
+ * or after {@link #onListenerDisconnected()}.
+ * </p>
  */
 public abstract class NotificationListenerService extends Service {
     // TAG = "NotificationListenerService[MySubclass]"
@@ -164,6 +170,7 @@
 
     /** @hide */
     protected NotificationListenerWrapper mWrapper = null;
+    private boolean isConnected = false;
 
     @GuardedBy("mLock")
     private RankingMap mRankingMap;
@@ -222,10 +229,10 @@
 
     /**
      * Implement this method to learn when notifications are removed.
-     * <P>
+     * <p>
      * This might occur because the user has dismissed the notification using system UI (or another
      * notification listener) or because the app has withdrawn the notification.
-     * <P>
+     * <p>
      * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
      * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
      * fields such as {@link android.app.Notification#contentView} and
@@ -243,10 +250,10 @@
 
     /**
      * Implement this method to learn when notifications are removed.
-     * <P>
+     * <p>
      * This might occur because the user has dismissed the notification using system UI (or another
      * notification listener) or because the app has withdrawn the notification.
-     * <P>
+     * <p>
      * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
      * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
      * fields such as {@link android.app.Notification#contentView} and
@@ -275,6 +282,15 @@
     }
 
     /**
+     * Implement this method to learn about when the listener is disconnected from the
+     * notification manager.You will not receive any events after this call, and may only
+     * call {@link #requestRebind(ComponentName)} at this time.
+     */
+    public void onListenerDisconnected() {
+        // optional
+    }
+
+    /**
      * Implement this method to be notified when the notification ranking changes.
      *
      * @param rankingMap The current ranking map that can be used to retrieve ranking information
@@ -322,12 +338,15 @@
      * It should be called after the user dismisses a single notification using your UI;
      * upon being informed, the notification manager will actually remove the notification
      * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
-     * <P>
+     * <p>
      * <b>Note:</b> If your listener allows the user to fire a notification's
      * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
      * this method at that time <i>if</i> the Notification in question has the
      * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @param pkg Package of the notifying app.
      * @param tag Tag of the notification as specified by the notifying app in
      *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
@@ -357,12 +376,16 @@
      * It should be called after the user dismisses a single notification using your UI;
      * upon being informed, the notification manager will actually remove the notification
      * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
-     * <P>
+     * <p>
      * <b>Note:</b> If your listener allows the user to fire a notification's
      * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
      * this method at that time <i>if</i> the Notification in question has the
      * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
      * <p>
+     *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @param key Notification to dismiss from {@link StatusBarNotification#getKey()}.
      */
     public final void cancelNotification(String key) {
@@ -384,6 +407,9 @@
      * upon being informed, the notification manager will actually remove all active notifications
      * and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * {@see #cancelNotification(String, String, int)}
      */
     public final void cancelAllNotifications() {
@@ -396,6 +422,9 @@
      * Use this if your listener has a user interface that allows the user to dismiss
      * multiple notifications at once.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @param keys Notifications to dismiss, or {@code null} to dismiss all.
      *
      * {@see #cancelNotification(String, String, int)}
@@ -414,6 +443,10 @@
      * user. This should only be called when there is sufficient confidence that the user is
      * looking at the notifications, such as when the notifications appear on the screen due to
      * an explicit user interaction.
+     *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @param keys Notifications to mark as seen.
      */
     public final void setNotificationsShown(String[] keys) {
@@ -436,6 +469,9 @@
      * <p>
      * Set to {@link #TRIM_FULL} initially.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @hide
      *
      * @param trim trim of the notifications to be passed via {@link #onNotificationPosted}.
@@ -455,6 +491,9 @@
      * Request the list of outstanding notifications (that is, those that are visible to the
      * current user). Useful when you don't know what's already been posted.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @return An array of active notifications, sorted in natural order.
      */
     public StatusBarNotification[] getActiveNotifications() {
@@ -480,6 +519,9 @@
      * notifications but didn't want to retain the bits, and now need to go back and extract
      * more data out of those notifications.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @param keys the keys of the notifications to request
      * @return An array of notifications corresponding to the requested keys, in the
      * same order as the key list.
@@ -545,6 +587,9 @@
      * shared across all listeners or a feature the notification host does not support or refuses
      * to grant.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @return Zero or more of the HINT_ constants.
      */
     public final int getCurrentListenerHints() {
@@ -572,6 +617,9 @@
      * <p>
      * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
      * unavailable.
      */
@@ -594,6 +642,9 @@
      * <p>
      * Listen for updates using {@link #onListenerHintsChanged(int)}.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @param hints One or more of the HINT_ constants.
      */
     public final void requestListenerHints(int hints) {
@@ -614,6 +665,9 @@
      * <p>
      * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @param interruptionFilter One of the INTERRUPTION_FILTER_ constants.
      */
     public final void requestInterruptionFilter(int interruptionFilter) {
@@ -640,6 +694,9 @@
      * such events, for example to retrieve the RankingMap right after
      * initialization.
      *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation.
+     *
      * @return A {@link RankingMap} object providing access to ranking information
      */
     public RankingMap getCurrentRanking() {
@@ -648,6 +705,12 @@
         }
     }
 
+    /**
+     * This is not the lifecycle event you are looking for.
+     *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing any operations.
+     */
     @Override
     public IBinder onBind(Intent intent) {
         if (mWrapper == null) {
@@ -665,6 +728,12 @@
         return true;
     }
 
+    @Override
+    public void onDestroy() {
+        onListenerDisconnected();
+        super.onDestroy();
+    }
+
     /**
      * Directly register this service with the Notification Manager.
      *
@@ -693,7 +762,7 @@
     /**
      * Directly unregister this service from the Notification Manager.
      *
-     * <P>This method will fail for listeners that were not registered
+     * <p>This method will fail for listeners that were not registered
      * with (@link registerAsService).
      * @hide
      */
@@ -708,11 +777,8 @@
     /**
      * Request that the listener be rebound, after a previous call to (@link requestUnbind).
      *
-     * <P>This method will fail for listeners that have
+     * <p>This method will fail for listeners that have
      * not been granted the permission by the user.
-     *
-     * <P>The service should wait for the {@link #onListenerConnected()} event
-     * before performing any operations.
      */
     public static void requestRebind(ComponentName componentName)
             throws RemoteException {
@@ -724,14 +790,19 @@
     /**
      * Request that the service be unbound.
      *
-     * <P>This will no longer receive updates until
+     * <p>This will no longer receive updates until
      * {@link #requestRebind(ComponentName)} is called.
      * The service will likely be kiled by the system after this call.
+     *
+     * <p>The service should wait for the {@link #onListenerConnected()} event
+     * before performing this operation. I know it's tempting, but you must wait.
      */
     public final void requestUnbind() throws RemoteException {
         if (mWrapper != null) {
             INotificationManager noMan = getNotificationInterface();
             noMan.requestUnbindListener(mWrapper);
+            // Disable future messages.
+            isConnected = false;
         }
     }
 
@@ -842,6 +913,7 @@
             synchronized (mLock) {
                 applyUpdateLocked(update);
             }
+            isConnected = true;
             mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_CONNECTED).sendToTarget();
         }
 
@@ -1303,6 +1375,9 @@
 
         @Override
         public void handleMessage(Message msg) {
+            if (!isConnected) {
+                return;
+            }
             switch (msg.what) {
                 case MSG_ON_NOTIFICATION_POSTED: {
                     SomeArgs args = (SomeArgs) msg.obj;
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index df774b4..c972476 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -794,8 +794,7 @@
         }
 
         final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
-        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length,
-                mRootNode.mNativeRenderNode);
+        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
         if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
             setEnabled(false);
             attachInfo.mViewRootImpl.mSurface.release();
@@ -994,8 +993,7 @@
     private static native void nSetLightCenter(long nativeProxy,
             float lightX, float lightY, float lightZ);
     private static native void nSetOpaque(long nativeProxy, boolean opaque);
-    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size,
-            long rootRenderNode);
+    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
     private static native void nDestroy(long nativeProxy, long rootRenderNode);
     private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b95d830..b0aa5c3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -20424,21 +20424,21 @@
          * the touch point.
          * </p>
          *
-         * @param shadowSize A {@link android.graphics.Point} containing the width and height
+         * @param outShadowSize A {@link android.graphics.Point} containing the width and height
          * of the shadow image. Your application must set {@link android.graphics.Point#x} to the
          * desired width and must set {@link android.graphics.Point#y} to the desired height of the
          * image.
          *
-         * @param shadowTouchPoint A {@link android.graphics.Point} for the position within the
+         * @param outShadowTouchPoint A {@link android.graphics.Point} for the position within the
          * shadow image that should be underneath the touch point during the drag and drop
          * operation. Your application must set {@link android.graphics.Point#x} to the
          * X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position.
          */
-        public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
+        public void onProvideShadowMetrics(Point outShadowSize, Point outShadowTouchPoint) {
             final View view = mView.get();
             if (view != null) {
-                shadowSize.set(view.getWidth(), view.getHeight());
-                shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
+                outShadowSize.set(view.getWidth(), view.getHeight());
+                outShadowTouchPoint.set(outShadowSize.x / 2, outShadowSize.y / 2);
             } else {
                 Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
             }
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index d8ed92d..339c2bf 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -208,7 +208,7 @@
     @Override
     public void show() {
         if (!tryShow()) {
-            throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
+            throw new IllegalStateException("StandardMenuPopup cannot be used without an anchor");
         }
     }
 
@@ -273,7 +273,7 @@
             mOnDismissListener = null;
 
             // Close this menu popup to make room for the submenu popup.
-            dismiss();
+            mMenu.close(false /* closeAllMenus */);
 
             // Show the new sub-menu popup at the same location as this popup.
             if (subPopup.tryShow(mXOffset, mYOffset)) {
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 27e2ee8..4459f32 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -128,9 +128,22 @@
 
 static void android_view_RenderNode_setDisplayList(JNIEnv* env,
         jobject clazz, jlong renderNodePtr, jlong displayListPtr) {
+    class RemovedObserver : public TreeObserver {
+    public:
+        virtual void onMaybeRemovedFromTree(RenderNode* node) override {
+            maybeRemovedNodes.insert(sp<RenderNode>(node));
+        }
+        std::set< sp<RenderNode> > maybeRemovedNodes;
+    };
+
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     DisplayList* newData = reinterpret_cast<DisplayList*>(displayListPtr);
-    renderNode->setStagingDisplayList(newData);
+    RemovedObserver observer;
+    renderNode->setStagingDisplayList(newData, &observer);
+    for (auto& node : observer.maybeRemovedNodes) {
+        if (node->hasParents()) continue;
+        onRenderNodeRemoved(env, node.get());
+    }
 }
 
 // ----------------------------------------------------------------------------
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 14252dc..21e4d2f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -525,7 +525,7 @@
     UiFrameInfoBuilder(proxy->frameInfo())
             .setVsync(vsync, vsync)
             .addFlag(FrameInfoFlags::SurfaceCanvas);
-    proxy->syncAndDrawFrame();
+    proxy->syncAndDrawFrame(nullptr);
 }
 
 static void destroy(JNIEnv* env, jclass clazz, jlong rendererPtr) {
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 8019326..3d65209 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -72,6 +72,31 @@
     return env;
 }
 
+// TODO: Clean this up, it's a bit odd to need to call over to
+// rendernode's jni layer. Probably means RootRenderNode should be pulled
+// into HWUI with appropriate callbacks for the various JNI hooks so
+// that RenderNode's JNI layer can handle its own thing
+void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
+
+class ScopedRemovedRenderNodeObserver : public TreeObserver {
+public:
+    ScopedRemovedRenderNodeObserver(JNIEnv* env) : mEnv(env) {}
+    ~ScopedRemovedRenderNodeObserver() {
+        for (auto& node : mMaybeRemovedNodes) {
+            if (node->hasParents()) continue;
+            onRenderNodeRemoved(mEnv, node.get());
+        }
+    }
+
+    virtual void onMaybeRemovedFromTree(RenderNode* node) override {
+        mMaybeRemovedNodes.insert(sp<RenderNode>(node));
+    }
+
+private:
+    JNIEnv* mEnv;
+    std::set< sp<RenderNode> > mMaybeRemovedNodes;
+};
+
 class OnFinishedEvent {
 public:
     OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
@@ -120,13 +145,7 @@
     std::string mMessage;
 };
 
-// TODO: Clean this up, it's a bit odd to need to call over to
-// rendernode's jni layer. Probably means RootRenderNode should be pulled
-// into HWUI with appropriate callbacks for the various JNI hooks so
-// that RenderNode's JNI layer can handle its own thing
-void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
-
-class RootRenderNode : public RenderNode, ErrorHandler, TreeObserver {
+class RootRenderNode : public RenderNode, ErrorHandler {
 public:
     RootRenderNode(JNIEnv* env) : RenderNode() {
         mLooper = Looper::getForThread();
@@ -143,9 +162,6 @@
 
     virtual void prepareTree(TreeInfo& info) override {
         info.errorHandler = this;
-        if (info.mode == TreeInfo::MODE_FULL) {
-            info.observer = this;
-        }
         // TODO: This is hacky
         info.windowInsetLeft = -stagingProperties().getLeft();
         info.windowInsetTop = -stagingProperties().getTop();
@@ -155,7 +171,6 @@
         info.windowInsetLeft = 0;
         info.windowInsetTop = 0;
         info.errorHandler = nullptr;
-        info.observer = nullptr;
     }
 
     void sendMessage(const sp<MessageHandler>& handler) {
@@ -181,27 +196,10 @@
         mPendingAnimatingRenderNodes.clear();
     }
 
-    virtual void onMaybeRemovedFromTree(RenderNode* node) override {
-        mMaybeRemovedNodes.insert(sp<RenderNode>(node));
-    }
-
-    void processMaybeRemovedNodes(JNIEnv* env) {
-        // We can safely access mMaybeRemovedNodes here because
-        // we will only modify it in prepareTree calls that are
-        // MODE_FULL
-
-        for (auto& node : mMaybeRemovedNodes) {
-            if (node->hasParents()) continue;
-            onRenderNodeRemoved(env, node.get());
-        }
-        mMaybeRemovedNodes.clear();
-    }
-
 private:
     sp<Looper> mLooper;
     JavaVM* mVm;
     std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
-    std::set< sp<RenderNode> > mMaybeRemovedNodes;
 };
 
 class AnimationContextBridge : public AnimationContext {
@@ -500,24 +498,23 @@
 }
 
 static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
-        jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize, jlong rootNodePtr) {
+        jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
     LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
             "Mismatched size expectations, given %d expected %d",
             frameInfoSize, UI_THREAD_FRAME_INFO_SIZE);
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
+    ScopedRemovedRenderNodeObserver observer(env);
     env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
-    int ret = proxy->syncAndDrawFrame();
-    rootRenderNode->processMaybeRemovedNodes(env);
-    return ret;
+    return proxy->syncAndDrawFrame(&observer);
 }
 
 static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jlong rootNodePtr) {
+    ScopedRemovedRenderNodeObserver observer(env);
     RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
     rootRenderNode->destroy();
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    proxy->destroy();
+    proxy->destroy(&observer);
 }
 
 static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
@@ -542,9 +539,10 @@
 
 static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jlong nodePtr) {
+    ScopedRemovedRenderNodeObserver observer(env);
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
     RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
-    proxy->buildLayer(node);
+    proxy->buildLayer(node, &observer);
 }
 
 static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
@@ -579,8 +577,9 @@
 
 static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
         jlong proxyPtr) {
+    ScopedRemovedRenderNodeObserver observer(env);
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    proxy->destroyHardwareResources();
+    proxy->destroyHardwareResources(&observer);
 }
 
 static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
@@ -736,7 +735,7 @@
     { "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
     { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
     { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
-    { "nSyncAndDrawFrame", "(J[JIJ)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
+    { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
     { "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
     { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
     { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b4f95dc..96731cf 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4018,12 +4018,6 @@
     <!-- Lock-to-app unlock password string -->
     <string name="lock_to_app_unlock_password">Ask for password before unpinning</string>
 
-    <!-- Multi-Window strings -->
-    <!-- Warning message when an app that got forced to be resizable gets shown in split-screen -->
-    <string name="dock_forced_resizable">App may not work with split-screen.</string>
-    <!-- Warning message when we try to dock a non-resizeble tasks and launch it in fullscreen instead. -->
-    <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
-
     <!-- Notification shown when device owner silently installs a package [CHAR LIMIT=NONE] -->
     <string name="package_installed_device_owner">Installed by your administrator</string>
     <!-- Notification shown when device owner silently updates a package [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2215bd4..d0414c3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -613,8 +613,6 @@
   <java-symbol type="string" name="display_manager_overlay_display_name" />
   <java-symbol type="string" name="display_manager_overlay_display_secure_suffix" />
   <java-symbol type="string" name="display_manager_overlay_display_title" />
-  <java-symbol type="string" name="dock_forced_resizable" />
-  <java-symbol type="string" name="dock_non_resizeble_failed_to_dock_text" />
   <java-symbol type="string" name="double_tap_toast" />
   <java-symbol type="string" name="durationDays" />
   <java-symbol type="string" name="durationDayHours" />
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index be816f78..0606b0b 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -248,16 +248,17 @@
     tests/unit/FatVectorTests.cpp \
     tests/unit/GlopBuilderTests.cpp \
     tests/unit/GpuMemoryTrackerTests.cpp \
+    tests/unit/GradientCacheTests.cpp \
     tests/unit/LayerUpdateQueueTests.cpp \
     tests/unit/LinearAllocatorTests.cpp \
     tests/unit/MatrixTests.cpp \
     tests/unit/OffscreenBufferPoolTests.cpp \
     tests/unit/RenderNodeTests.cpp \
     tests/unit/SkiaBehaviorTests.cpp \
+    tests/unit/SnapshotTests.cpp \
     tests/unit/StringUtilsTests.cpp \
     tests/unit/TextDropShadowCacheTests.cpp \
-    tests/unit/VectorDrawableTests.cpp \
-    tests/unit/GradientCacheTests.cpp
+    tests/unit/VectorDrawableTests.cpp
 
 ifeq (true, $(HWUI_NEW_OPS))
     LOCAL_SRC_FILES += \
diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp
index b70d586..9f98241 100644
--- a/libs/hwui/BakedOpState.cpp
+++ b/libs/hwui/BakedOpState.cpp
@@ -50,7 +50,7 @@
     }
 
     // resolvedClipRect = intersect(parentMatrix * localClip, parentClip)
-    clipState = snapshot.mutateClipArea().serializeIntersectedClip(allocator,
+    clipState = snapshot.serializeIntersectedClip(allocator,
             recordedOp.localClip, *(snapshot.transform));
     LOG_ALWAYS_FATAL_IF(!clipState, "must clip!");
 
@@ -85,8 +85,7 @@
 ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
         const Matrix4& localTransform, const ClipBase* localClip) {
     transform.loadMultiply(*snapshot.transform, localTransform);
-    clipState = snapshot.mutateClipArea().serializeIntersectedClip(allocator,
-            localClip, *(snapshot.transform));
+    clipState = snapshot.serializeIntersectedClip(allocator, localClip, *(snapshot.transform));
     clippedBounds = clipState->rect;
     clipSideFlags = OpClipSideFlags::Full;
     localProjectionPathMask = nullptr;
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index f886dda..35fe06d 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -217,6 +217,7 @@
 
 void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
         SkRegion::Op op) {
+    if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
     if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
     onClipUpdated();
     switch (mMode) {
@@ -233,6 +234,7 @@
 }
 
 void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
+    if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
     if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
     onClipUpdated();
     enterRegionMode();
@@ -242,6 +244,7 @@
 
 void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
         SkRegion::Op op) {
+    if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
     if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
     onClipUpdated();
     SkMatrix skTransform;
@@ -379,6 +382,7 @@
             serialization->rect.set(mClipRegion.getBounds());
             break;
         }
+        serialization->intersectWithRoot = mReplaceOpObserved;
         // TODO: this is only done for draw time, should eventually avoid for record time
         serialization->rect.snapToPixelBoundaries();
         mLastSerialization = serialization;
diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h
index 1654eb8..6eb2eef 100644
--- a/libs/hwui/ClipArea.h
+++ b/libs/hwui/ClipArea.h
@@ -103,6 +103,7 @@
             : mode(ClipMode::Rectangle)
             , rect(rect) {}
     const ClipMode mode;
+    bool intersectWithRoot = false;
     // Bounds of the clipping area, used to define the scissor, and define which
     // portion of the stencil is updated/used
     Rect rect;
@@ -173,8 +174,8 @@
         return mMode == ClipMode::RectangleList;
     }
 
-    const ClipBase* serializeClip(LinearAllocator& allocator);
-    const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
+    WARN_UNUSED_RESULT const ClipBase* serializeClip(LinearAllocator& allocator);
+    WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
             const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
     void applyClip(const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
 
@@ -214,6 +215,7 @@
 
     ClipMode mMode;
     bool mPostViewportClipObserved = false;
+    bool mReplaceOpObserved = false;
 
     /**
      * If mLastSerialization is non-null, it represents an already serialized copy
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 0401f2d..f12e523 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -462,7 +462,7 @@
     int count = mCanvasState.save(SaveFlags::MatrixClip);
 
     // apply state from RecordedOp (clip first, since op's clip is transformed by current matrix)
-    mCanvasState.writableSnapshot()->mutateClipArea().applyClip(op.localClip,
+    mCanvasState.writableSnapshot()->applyClip(op.localClip,
             *mCanvasState.currentSnapshot()->transform);
     mCanvasState.concatMatrix(op.localMatrix);
 
diff --git a/libs/hwui/OpDumper.cpp b/libs/hwui/OpDumper.cpp
index c34cfbe..cab93e8 100644
--- a/libs/hwui/OpDumper.cpp
+++ b/libs/hwui/OpDumper.cpp
@@ -33,10 +33,15 @@
     op.localMatrix.mapRect(localBounds);
     output << sOpNameLut[op.opId] << " " << localBounds;
 
-    if (op.localClip && !op.localClip->rect.contains(localBounds)) {
+    if (op.localClip
+            && (!op.localClip->rect.contains(localBounds) || op.localClip->intersectWithRoot)) {
         output << std::fixed << std::setprecision(0)
              << " clip=" << op.localClip->rect
              << " mode=" << (int)op.localClip->mode;
+
+        if (op.localClip->intersectWithRoot) {
+             output << " iwr";
+        }
     }
 }
 
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 9578486..ea06fcd 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -81,14 +81,14 @@
 #endif
 }
 
-void RenderNode::setStagingDisplayList(DisplayList* displayList) {
+void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* observer) {
     mNeedsDisplayListSync = true;
     delete mStagingDisplayList;
     mStagingDisplayList = displayList;
     // If mParentCount == 0 we are the sole reference to this RenderNode,
     // so immediately free the old display list
     if (!mParentCount && !mStagingDisplayList) {
-        deleteDisplayList(nullptr);
+        deleteDisplayList(observer);
     }
 }
 
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index b0136cf..acdc3d8 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -117,7 +117,7 @@
 
     void debugDumpLayers(const char* prefix);
 
-    ANDROID_API void setStagingDisplayList(DisplayList* newData);
+    ANDROID_API void setStagingDisplayList(DisplayList* newData, TreeObserver* observer);
 
     void computeOrdering();
 
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index d784280..2c9c9d9 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -242,6 +242,33 @@
 #endif
 }
 
+static Snapshot* getClipRoot(Snapshot* target) {
+    while (target->previous && target->previous->previous) {
+        target = target->previous;
+    }
+    return target;
+}
+
+const ClipBase* Snapshot::serializeIntersectedClip(LinearAllocator& allocator,
+        const ClipBase* recordedClip, const Matrix4& recordedClipTransform) {
+    auto target = this;
+    if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) {
+        // Clip must be intersected with root, instead of current clip.
+        target = getClipRoot(this);
+    }
+
+    return target->mClipArea->serializeIntersectedClip(allocator,
+            recordedClip, recordedClipTransform);
+}
+
+void Snapshot::applyClip(const ClipBase* recordedClip, const Matrix4& transform) {
+    if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) {
+        // current clip is being replaced, but must intersect with clip root
+        *mClipArea = *(getClipRoot(this)->mClipArea);
+    }
+    mClipArea->applyClip(recordedClip, transform);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Queries
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 3a01d04..d8f926e 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -170,6 +170,10 @@
     const ClipArea& getClipArea() const { return *mClipArea; }
     ClipArea& mutateClipArea() { return *mClipArea; }
 
+    WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
+            const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
+    void applyClip(const ClipBase* clip, const Matrix4& transform);
+
     /**
      * Resets the clip to the specified rect.
      */
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 63fa788..ab66b2a 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -76,15 +76,15 @@
 }
 
 CanvasContext::~CanvasContext() {
-    destroy();
+    destroy(nullptr);
     mRenderThread.renderState().unregisterCanvasContext(this);
 }
 
-void CanvasContext::destroy() {
+void CanvasContext::destroy(TreeObserver* observer) {
     stopDrawing();
     setSurface(nullptr);
-    freePrefetechedLayers();
-    destroyHardwareResources();
+    freePrefetchedLayers(observer);
+    destroyHardwareResources(observer);
     mAnimationContext->destroy();
 #if !HWUI_NEW_OPS
     if (mCanvas) {
@@ -222,7 +222,7 @@
     mAnimationContext->runRemainingAnimations(info);
     GL_CHECKPOINT(MODERATE);
 
-    freePrefetechedLayers();
+    freePrefetchedLayers(info.observer);
     GL_CHECKPOINT(MODERATE);
 
     if (CC_UNLIKELY(!mNativeSurface.get())) {
@@ -569,25 +569,24 @@
 }
 
 void CanvasContext::markLayerInUse(RenderNode* node) {
-    if (mPrefetechedLayers.erase(node)) {
+    if (mPrefetchedLayers.erase(node)) {
         node->decStrong(nullptr);
     }
 }
 
-static void destroyPrefetechedNode(RenderNode* node) {
-    ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName());
-    node->destroyHardwareResources(nullptr);
-    node->decStrong(nullptr);
-}
-
-void CanvasContext::freePrefetechedLayers() {
-    if (mPrefetechedLayers.size()) {
-        std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
-        mPrefetechedLayers.clear();
+void CanvasContext::freePrefetchedLayers(TreeObserver* observer) {
+    if (mPrefetchedLayers.size()) {
+        for (auto& node : mPrefetchedLayers) {
+            ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...",
+                    node->getName());
+            node->destroyHardwareResources(observer);
+            node->decStrong(observer);
+        }
+        mPrefetchedLayers.clear();
     }
 }
 
-void CanvasContext::buildLayer(RenderNode* node) {
+void CanvasContext::buildLayer(RenderNode* node, TreeObserver* observer) {
     ATRACE_CALL();
     if (!mEglManager.hasEglContext()) return;
 #if !HWUI_NEW_OPS
@@ -599,6 +598,7 @@
 
     TreeInfo info(TreeInfo::MODE_FULL, *this);
     info.damageAccumulator = &mDamageAccumulator;
+    info.observer = observer;
 #if HWUI_NEW_OPS
     info.layerUpdateQueue = &mLayerUpdateQueue;
 #else
@@ -628,7 +628,7 @@
 #endif
 
     node->incStrong(nullptr);
-    mPrefetechedLayers.insert(node);
+    mPrefetchedLayers.insert(node);
 }
 
 bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
@@ -636,12 +636,12 @@
     return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
 }
 
-void CanvasContext::destroyHardwareResources() {
+void CanvasContext::destroyHardwareResources(TreeObserver* observer) {
     stopDrawing();
     if (mEglManager.hasEglContext()) {
-        freePrefetechedLayers();
+        freePrefetchedLayers(observer);
         for (const sp<RenderNode>& node : mRenderNodes) {
-            node->destroyHardwareResources(nullptr);
+            node->destroyHardwareResources(observer);
         }
         Caches& caches = Caches::getInstance();
         // Make sure to release all the textures we were owning as there won't
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6d0889e..9350114 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -92,17 +92,17 @@
     void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
             int64_t syncQueued, RenderNode* target);
     void draw();
-    void destroy();
+    void destroy(TreeObserver* observer);
 
     // IFrameCallback, Choreographer-driven frame callback entry point
     virtual void doFrame() override;
     void prepareAndDraw(RenderNode* node);
 
-    void buildLayer(RenderNode* node);
+    void buildLayer(RenderNode* node, TreeObserver* observer);
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
     void markLayerInUse(RenderNode* node);
 
-    void destroyHardwareResources();
+    void destroyHardwareResources(TreeObserver* observer);
     static void trimMemory(RenderThread& thread, int level);
 
     static void invokeFunctor(RenderThread& thread, Functor* functor);
@@ -174,7 +174,7 @@
     void setSurface(Surface* window);
     void requireSurface();
 
-    void freePrefetechedLayers();
+    void freePrefetchedLayers(TreeObserver* observer);
 
     void waitOnFences();
 
@@ -218,7 +218,7 @@
     FrameInfoVisualizer mProfiler;
     std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
 
-    std::set<RenderNode*> mPrefetechedLayers;
+    std::set<RenderNode*> mPrefetchedLayers;
 
     // Stores the bounds of the main content.
     Rect mContentDrawBounds;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index e8b9725..651aaa2 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -65,11 +65,12 @@
     }
 }
 
-int DrawFrameTask::drawFrame() {
+int DrawFrameTask::drawFrame(TreeObserver* observer) {
     LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
 
     mSyncResult = kSync_OK;
     mSyncQueued = systemTime(CLOCK_MONOTONIC);
+    mObserver = observer;
     postAndWait();
 
     return mSyncResult;
@@ -88,6 +89,7 @@
     bool canDrawThisFrame;
     {
         TreeInfo info(TreeInfo::MODE_FULL, *mContext);
+        info.observer = mObserver;
         canUnblockUiThread = syncFrameState(info);
         canDrawThisFrame = info.out.canDrawThisFrame;
     }
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index cae251a9..9bba065 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -62,7 +62,7 @@
     void pushLayerUpdate(DeferredLayerUpdater* layer);
     void removeLayerUpdate(DeferredLayerUpdater* layer);
 
-    int drawFrame();
+    int drawFrame(TreeObserver* observer);
 
     int64_t* frameInfo() { return mFrameInfo; }
 
@@ -87,6 +87,7 @@
 
     int mSyncResult;
     int64_t mSyncQueued;
+    TreeObserver* mObserver;
 
     int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
 };
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 16dd108..2e99d0b 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -222,18 +222,19 @@
     return mDrawFrameTask.frameInfo();
 }
 
-int RenderProxy::syncAndDrawFrame() {
-    return mDrawFrameTask.drawFrame();
+int RenderProxy::syncAndDrawFrame(TreeObserver* observer) {
+    return mDrawFrameTask.drawFrame(observer);
 }
 
-CREATE_BRIDGE1(destroy, CanvasContext* context) {
-    args->context->destroy();
+CREATE_BRIDGE2(destroy, CanvasContext* context, TreeObserver* observer) {
+    args->context->destroy(args->observer);
     return nullptr;
 }
 
-void RenderProxy::destroy() {
+void RenderProxy::destroy(TreeObserver* observer) {
     SETUP_TASK(destroy);
     args->context = mContext;
+    args->observer = observer;
     // destroyCanvasAndSurface() needs a fence as when it returns the
     // underlying BufferQueue is going to be released from under
     // the render thread.
@@ -287,15 +288,16 @@
     return layer;
 }
 
-CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) {
-    args->context->buildLayer(args->node);
+CREATE_BRIDGE3(buildLayer, CanvasContext* context, RenderNode* node, TreeObserver* observer) {
+    args->context->buildLayer(args->node, args->observer);
     return nullptr;
 }
 
-void RenderProxy::buildLayer(RenderNode* node) {
+void RenderProxy::buildLayer(RenderNode* node, TreeObserver* observer) {
     SETUP_TASK(buildLayer);
     args->context = mContext;
     args->node = node;
+    args->observer = observer;
     postAndWait(task);
 }
 
@@ -332,15 +334,16 @@
     postAndWait(task);
 }
 
-CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) {
-    args->context->destroyHardwareResources();
+CREATE_BRIDGE2(destroyHardwareResources, CanvasContext* context, TreeObserver* observer) {
+    args->context->destroyHardwareResources(args->observer);
     return nullptr;
 }
 
-void RenderProxy::destroyHardwareResources() {
+void RenderProxy::destroyHardwareResources(TreeObserver* observer) {
     SETUP_TASK(destroyHardwareResources);
     args->context = mContext;
-    post(task);
+    args->observer = observer;
+    postAndWait(task);
 }
 
 CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 8d65a82..97194fe 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -42,6 +42,7 @@
 class DisplayList;
 class Layer;
 class Rect;
+class TreeObserver;
 
 namespace renderthread {
 
@@ -75,21 +76,21 @@
     ANDROID_API void setLightCenter(const Vector3& lightCenter);
     ANDROID_API void setOpaque(bool opaque);
     ANDROID_API int64_t* frameInfo();
-    ANDROID_API int syncAndDrawFrame();
-    ANDROID_API void destroy();
+    ANDROID_API int syncAndDrawFrame(TreeObserver* observer);
+    ANDROID_API void destroy(TreeObserver* observer);
 
     ANDROID_API static void invokeFunctor(Functor* functor, bool waitForCompletion);
 
     ANDROID_API void runWithGlContext(RenderTask* task);
 
     ANDROID_API DeferredLayerUpdater* createTextureLayer();
-    ANDROID_API void buildLayer(RenderNode* node);
+    ANDROID_API void buildLayer(RenderNode* node, TreeObserver* observer);
     ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
     ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
     ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
     ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);
 
-    ANDROID_API void destroyHardwareResources();
+    ANDROID_API void destroyHardwareResources(TreeObserver* observer);
     ANDROID_API static void trimMemory(int level);
     ANDROID_API static void overrideProperty(const char* name, const char* value);
 
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 5492035..5f4ebc0 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -146,7 +146,7 @@
         if (setup) {
             TestCanvas canvas(props.getWidth(), props.getHeight());
             setup(props, canvas);
-            node->setStagingDisplayList(canvas.finishRecording());
+            node->setStagingDisplayList(canvas.finishRecording(), nullptr);
         }
         node->setPropertyFieldsDirty(0xFFFFFFFF);
         return node;
@@ -157,7 +157,7 @@
        TestCanvas canvas(node.stagingProperties().getWidth(),
                node.stagingProperties().getHeight());
        contentCallback(canvas);
-       node.setStagingDisplayList(canvas.finishRecording());
+       node.setStagingDisplayList(canvas.finishRecording(), nullptr);
     }
 
     /**
diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
index 63c067b..f184411 100644
--- a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
@@ -59,6 +59,6 @@
                     0, 100 * (i + 2), kBidi_Force_LTR, paint, nullptr);
         }
 
-        container->setStagingDisplayList(canvas.finishRecording());
+        container->setStagingDisplayList(canvas.finishRecording(), nullptr);
     }
 };
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index ab368c05..8035dc4 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -76,7 +76,7 @@
             // draw it to parent DisplayList
             canvas.drawRenderNode(cards[ci].get());
         }
-        listView->setStagingDisplayList(canvas.finishRecording());
+        listView->setStagingDisplayList(canvas.finishRecording(), nullptr);
     }
 private:
     SkBitmap createRandomCharIcon() {
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 58c0876..cc0fdd5 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -95,7 +95,7 @@
         testContext.waitForVsync();
         nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
         UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
-        proxy->syncAndDrawFrame();
+        proxy->syncAndDrawFrame(nullptr);
     }
 
     proxy->resetProfileInfo();
@@ -110,7 +110,7 @@
             ATRACE_NAME("UI-Draw Frame");
             UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
             scene->doFrame(i);
-            proxy->syncAndDrawFrame();
+            proxy->syncAndDrawFrame(nullptr);
         }
         if (opts.reportFrametimeWeight) {
             proxy->fence();
diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
index 822d04f..b864703 100644
--- a/libs/hwui/tests/unit/ClipAreaTests.cpp
+++ b/libs/hwui/tests/unit/ClipAreaTests.cpp
@@ -132,8 +132,7 @@
         auto serializedClip = area.serializeClip(allocator);
         ASSERT_NE(nullptr, serializedClip);
         ASSERT_EQ(ClipMode::Rectangle, serializedClip->mode);
-        auto clipRect = reinterpret_cast<const ClipRect*>(serializedClip);
-        EXPECT_EQ(Rect(200, 200), clipRect->rect);
+        EXPECT_EQ(Rect(200, 200), serializedClip->rect);
         EXPECT_EQ(serializedClip, area.serializeClip(allocator))
                 << "Requery of clip on unmodified ClipArea must return same pointer.";
     }
@@ -192,8 +191,7 @@
         auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale);
         ASSERT_NE(nullptr, resolvedClip);
         ASSERT_EQ(ClipMode::Rectangle, resolvedClip->mode);
-        EXPECT_EQ(Rect(100, 100, 200, 200),
-                reinterpret_cast<const ClipRect*>(resolvedClip)->rect);
+        EXPECT_EQ(Rect(100, 100, 200, 200), resolvedClip->rect);
 
         EXPECT_EQ(resolvedClip, area.serializeIntersectedClip(allocator, &recordedClip, translateScale))
                 << "Must return previous serialization, since input is same";
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 0ea246f..9877439 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -1946,5 +1946,28 @@
     EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), observedData.rectMatrix);
 }
 
+RENDERTHREAD_TEST(FrameBuilder, clip_replace) {
+    class ClipReplaceTestRenderer : public TestRendererBase {
+    public:
+        void onColorOp(const ColorOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(0, mIndex++);
+            EXPECT_TRUE(op.localClip->intersectWithRoot);
+            EXPECT_EQ(Rect(20, 10, 30, 40), state.computedState.clipState->rect)
+                    << "Expect resolved clip to be intersection of viewport clip and clip op";
+        }
+    };
+    auto node = TestUtils::createNode(20, 20, 30, 30,
+            [](RenderProperties& props, RecordingCanvas& canvas) {
+        canvas.clipRect(0, -20, 10, 30, SkRegion::kReplace_Op);
+        canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
+    });
+
+    FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeLTRB(10, 10, 40, 40), 50, 50,
+            TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
+    ClipReplaceTestRenderer renderer;
+    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(1, renderer.getIndex());
+}
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 58376c6..c49ff71 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -569,6 +569,19 @@
     EXPECT_CLIP_RECT(Rect(-100, -100, 300, 300), dl->getOps()[0]->localClip);
 }
 
+TEST(RecordingCanvas, replaceClipIntersectWithRoot) {
+    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
+        canvas.save(SaveFlags::MatrixClip);
+        canvas.clipRect(-10, -10, 110, 110, SkRegion::kReplace_Op);
+        canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
+        canvas.restore();
+    });
+    ASSERT_EQ(1u, dl->getOps().size()) << "Must have one op";
+    // first clip must be preserved, even if it extends beyond canvas bounds
+    EXPECT_CLIP_RECT(Rect(-10, -10, 110, 110), dl->getOps()[0]->localClip);
+    EXPECT_TRUE(dl->getOps()[0]->localClip->intersectWithRoot);
+}
+
 TEST(RecordingCanvas, insertReorderBarrier) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         canvas.drawRect(0, 0, 400, 400, SkPaint());
diff --git a/libs/hwui/tests/unit/SnapshotTests.cpp b/libs/hwui/tests/unit/SnapshotTests.cpp
new file mode 100644
index 0000000..11797a8
--- /dev/null
+++ b/libs/hwui/tests/unit/SnapshotTests.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <Snapshot.h>
+
+#include <tests/common/TestUtils.h>
+
+using namespace android::uirenderer;
+
+TEST(Snapshot, serializeIntersectedClip) {
+    auto actualRoot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 100));
+    auto root = TestUtils::makeSnapshot(Matrix4::identity(), Rect(10, 10, 90, 90));
+    auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
+    root->previous = actualRoot.get();
+    child->previous = root.get();
+
+    LinearAllocator allocator;
+    ClipRect rect(Rect(0, 0, 75, 75));
+    {
+        auto intersectWithChild = child->serializeIntersectedClip(allocator,
+                &rect, Matrix4::identity());
+        ASSERT_NE(nullptr, intersectWithChild);
+        EXPECT_EQ(Rect(50, 50, 75, 75), intersectWithChild->rect) << "Expect intersect with child";
+    }
+
+    rect.intersectWithRoot = true;
+    {
+        auto intersectWithRoot = child->serializeIntersectedClip(allocator,
+                &rect, Matrix4::identity());
+        ASSERT_NE(nullptr, intersectWithRoot);
+        EXPECT_EQ(Rect(10, 10, 75, 75), intersectWithRoot->rect) << "Expect intersect with root";
+    }
+}
+
+TEST(Snapshot, applyClip) {
+    auto actualRoot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 100));
+    auto root = TestUtils::makeSnapshot(Matrix4::identity(), Rect(10, 10, 90, 90));
+    root->previous = actualRoot.get();
+
+    ClipRect rect(Rect(0, 0, 75, 75));
+    {
+        auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
+        child->previous = root.get();
+        child->applyClip(&rect, Matrix4::identity());
+
+        EXPECT_TRUE(child->getClipArea().isSimple());
+        EXPECT_EQ(Rect(50, 50, 75, 75), child->getRenderTargetClip());
+    }
+
+    {
+        rect.intersectWithRoot = true;
+        auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
+        child->previous = root.get();
+        child->applyClip(&rect, Matrix4::identity());
+
+        EXPECT_TRUE(child->getClipArea().isSimple());
+        EXPECT_EQ(Rect(10, 10, 75, 75), child->getRenderTargetClip());
+    }
+}
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index b0431ce..b3195c4 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -104,8 +104,8 @@
     }
 
     void finishDrawing() {
-        mRootNode->setStagingDisplayList(mCanvas->finishRecording());
-        mProxy->syncAndDrawFrame();
+        mRootNode->setStagingDisplayList(mCanvas->finishRecording(), nullptr);
+        mProxy->syncAndDrawFrame(nullptr);
         // Surprisingly, calling mProxy->fence() here appears to make no difference to
         // the timings we record.
     }
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index df42a73..d1b1be9 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -22,7 +22,8 @@
 
 /**
  * A class containing a GPS clock timestamp.
- * It represents a measurement of the GPS receiver's clock.
+ *
+ * <p>It represents a measurement of the GPS receiver's clock.
  */
 public final class GnssClock implements Parcelable {
     // The following enumerations must be in sync with the values declared in gps.h
@@ -85,7 +86,7 @@
     }
 
     /**
-     * Returns true if {@link #getLeapSecond()} is available, false otherwise.
+     * Returns {@code true} if {@link #getLeapSecond()} is available, {@code false} otherwise.
      */
     public boolean hasLeapSecond() {
         return isFlagSet(HAS_LEAP_SECOND);
@@ -93,10 +94,12 @@
 
     /**
      * Gets the leap second associated with the clock's time.
-     * The sign of the value is defined by the following equation:
-     *      utc_time_ns = time_ns + (full_bias_ns + bias_ns) - leap_second * 1,000,000,000
      *
-     * The value is only available if {@link #hasLeapSecond()} is true.
+     * <p>The sign of the value is defined by the following equation:
+     * <pre>
+     *     UtcTimeNanos = TimeNanos + (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000</pre>
+     *
+     * <p>The value is only available if {@link #hasLeapSecond()} is {@code true}.
      */
     public int getLeapSecond() {
         return mLeapSecond;
@@ -123,18 +126,15 @@
     }
 
     /**
-     * Gets the GNSS receiver internal clock value in nanoseconds.
+     * Gets the GNSS receiver internal hardware clock value in nanoseconds.
      *
-     * For 'local hardware clock' this value is expected to be monotonically increasing during the
-     * reporting session. The real GPS time can be derived by compensating
-     * {@link #getFullBiasNanos()} (when it is available) from this value.
+     * <p>This value is expected to be monotonically increasing while the hardware clock remains
+     * powered on. For the case of a hardware clock that is not continuously on, see the
+     * {@link #getHardwareClockDiscontinuityCount} field. The GPS time can be derived by adding
+     * {@link #getFullBiasNanos()} and {@link #getBiasNanos()} (when they are available) to this
+     * value. Sub-nanosecond accuracy can be provided by means of {@link #getBiasNanos()}.
      *
-     * For 'GPS time' this value is expected to be the best estimation of current GPS time that GPS
-     * receiver can achieve. {@link #getTimeUncertaintyNanos()} should be available when GPS time is
-     * specified.
-     *
-     * Sub-nanosecond accuracy can be provided by means of {@link #getBiasNanos()}.
-     * The reported time includes {@link #getTimeUncertaintyNanos()}.
+     * <p>The error estimate for this value (if applicable) is {@link #getTimeUncertaintyNanos()}.
      */
     public long getTimeNanos() {
         return mTimeNanos;
@@ -150,7 +150,8 @@
     }
 
     /**
-     * Returns true if {@link #getTimeUncertaintyNanos()} is available, false otherwise.
+     * Returns {@code true} if {@link #getTimeUncertaintyNanos()} is available, {@code false}
+     * otherwise.
      */
     public boolean hasTimeUncertaintyNanos() {
         return isFlagSet(HAS_TIME_UNCERTAINTY);
@@ -158,9 +159,13 @@
 
     /**
      * Gets the clock's time Uncertainty (1-Sigma) in nanoseconds.
-     * The uncertainty is represented as an absolute (single sided) value.
      *
-     * The value is only available if {@link #hasTimeUncertaintyNanos()} is true.
+     * <p>The uncertainty is represented as an absolute (single sided) value.
+     *
+     * <p>The value is only available if {@link #hasTimeUncertaintyNanos()} is {@code true}.
+     *
+     * <p>This value is often effectively zero (it is the reference clock by which all other times
+     * and time uncertainties are measured), and thus this field may often be 0, or not provided.
      */
     public double getTimeUncertaintyNanos() {
         return mTimeUncertaintyNanos;
@@ -187,7 +192,7 @@
     }
 
     /**
-     * Returns true if {@link #getFullBiasNanos()} is available, false otherwise.
+     * Returns {@code true} if {@link #getFullBiasNanos()} is available, {@code false} otherwise.
      */
     public boolean hasFullBiasNanos() {
         return isFlagSet(HAS_FULL_BIAS);
@@ -197,14 +202,18 @@
      * Gets the difference between hardware clock ({@link #getTimeNanos()}) inside GPS receiver and
      * the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
      *
-     * This value is available if the receiver has estimated GPS time. If the computed time is for a
-     * non-GPS constellation, the time offset of that constellation to GPS has to be applied to fill
-     * this value. The value contains the 'bias uncertainty' {@link #getBiasUncertaintyNanos()} in
-     * it, and it should be used for quality check. The value is only available if
-     * {@link #hasFullBiasNanos()} is true.
+     * <p>This value is available if the receiver has estimated GPS time. If the computed time is
+     * for a non-GPS constellation, the time offset of that constellation to GPS has to be applied
+     * to fill this value. The value is only available if {@link #hasFullBiasNanos()} is
+     * {@code true}.
      *
-     * The sign of the value is defined by the following equation:
-     *      local estimate of GPS time = time_ns + (full_bias_ns + bias_ns)
+     * <p>The error estimate for the sum of this field and {@link #getBiasNanos} is
+     * {@link #getBiasUncertaintyNanos()}.
+     *
+     * <p>The sign of the value is defined by the following equation:
+     *
+     * <pre>
+     *     local estimate of GPS time = TimeNanos + (FullBiasNanos + BiasNanos)</pre>
      */
     public long getFullBiasNanos() {
         return mFullBiasNanos;
@@ -231,7 +240,7 @@
     }
 
     /**
-     * Returns true if {@link #getBiasNanos()} is available, false otherwise.
+     * Returns {@code true} if {@link #getBiasNanos()} is available, {@code false} otherwise.
      */
     public boolean hasBiasNanos() {
         return isFlagSet(HAS_BIAS);
@@ -239,9 +248,14 @@
 
     /**
      * Gets the clock's sub-nanosecond bias.
-     * The reported bias includes {@link #getBiasUncertaintyNanos()}.
      *
-     * The value is only available if {@link #hasBiasNanos()} is true.
+     * <p>See the description of how this field is part of converting from hardware clock time, to
+     * GPS time, in {@link #getFullBiasNanos()}.
+     *
+     * <p>The error estimate for the sum of this field and {@link #getFullBiasNanos} is
+     * {@link #getBiasUncertaintyNanos()}.
+     *
+     * <p>The value is only available if {@link #hasBiasNanos()} is {@code true}.
      */
     public double getBiasNanos() {
         return mBiasNanos;
@@ -268,7 +282,8 @@
     }
 
     /**
-     * Returns true if {@link #getBiasUncertaintyNanos()} is available, false otherwise.
+     * Returns {@code true} if {@link #getBiasUncertaintyNanos()} is available, {@code false}
+     * otherwise.
      */
     public boolean hasBiasUncertaintyNanos() {
         return isFlagSet(HAS_BIAS_UNCERTAINTY);
@@ -277,7 +292,10 @@
     /**
      * Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
      *
-     * The value is only available if {@link #hasBiasUncertaintyNanos()} is true.
+     * <p>See the description of how this field provides the error estimate in the conversion from
+     * hardware clock time, to GPS time, in {@link #getFullBiasNanos()}.
+     *
+     * <p>The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}.
      */
     public double getBiasUncertaintyNanos() {
         return mBiasUncertaintyNanos;
@@ -304,7 +322,8 @@
     }
 
     /**
-     * Returns true if {@link #getDriftNanosPerSecond()} is available, false otherwise.
+     * Returns {@code true} if {@link #getDriftNanosPerSecond()} is available, {@code false}
+     * otherwise.
      */
     public boolean hasDriftNanosPerSecond() {
         return isFlagSet(HAS_DRIFT);
@@ -312,10 +331,12 @@
 
     /**
      * Gets the clock's Drift in nanoseconds per second.
-     * A positive value indicates that the frequency is higher than the nominal frequency.
-     * The reported drift includes {@link #getDriftUncertaintyNanosPerSecond()}.
      *
-     * The value is only available if {@link #hasDriftNanosPerSecond()} is true.
+     * <p>A positive value indicates that the frequency is higher than the nominal (e.g. GPS master
+     * clock) frequency. The error estimate for this reported drift is
+     * {@link #getDriftUncertaintyNanosPerSecond()}.
+     *
+     * <p>The value is only available if {@link #hasDriftNanosPerSecond()} is {@code true}.
      */
     public double getDriftNanosPerSecond() {
         return mDriftNanosPerSecond;
@@ -342,7 +363,8 @@
     }
 
     /**
-     * Returns true if {@link #getDriftUncertaintyNanosPerSecond()} is available, false otherwise.
+     * Returns {@code true} if {@link #getDriftUncertaintyNanosPerSecond()} is available,
+     * {@code false} otherwise.
      */
     public boolean hasDriftUncertaintyNanosPerSecond() {
         return isFlagSet(HAS_DRIFT_UNCERTAINTY);
@@ -351,7 +373,8 @@
     /**
      * Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
      *
-     * The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is true.
+     * <p>The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is
+     * {@code true}.
      */
     public double getDriftUncertaintyNanosPerSecond() {
         return mDriftUncertaintyNanosPerSecond;
@@ -368,7 +391,29 @@
     }
 
     /**
-     * Gets count of last hardware clock discontinuity.
+     * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+     * @hide
+     */
+    @TestApi
+    public void resetDriftUncertaintyNanosPerSecond() {
+        resetFlag(HAS_DRIFT_UNCERTAINTY);
+        mDriftUncertaintyNanosPerSecond = Double.NaN;
+    }
+
+    /**
+     * Gets count of hardware clock discontinuities.
+     *
+     * <p>When this value stays the same, vs. a value in a previously reported {@link GnssClock}, it
+     * can be safely assumed that the {@code TimeNanos} value has been derived from a clock that has
+     * been running continuously - e.g. a single continuously powered crystal oscillator, and thus
+     * the {@code (FullBiasNanos + BiasNanos)} offset can be modelled with traditional clock bias
+     * &amp; drift models.
+     *
+     * <p>Each time this value changes, vs. the value in a previously reported {@link GnssClock},
+     * that suggests the hardware clock may have experienced a discontinuity (e.g. a power cycle or
+     * other anomaly), so that any assumptions about modelling a smoothly changing
+     * {@code (FullBiasNanos + BiasNanos)} offset, and a smoothly growing {@code (TimeNanos)}
+     * between this and the previously reported {@code GnssClock}, should be reset.
      */
     public int getHardwareClockDiscontinuityCount() {
         return mHardwareClockDiscontinuityCount;
@@ -383,16 +428,6 @@
         mHardwareClockDiscontinuityCount = value;
     }
 
-    /**
-     * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
-     * @hide
-     */
-    @TestApi
-    public void resetDriftUncertaintyNanosPerSecond() {
-        resetFlag(HAS_DRIFT_UNCERTAINTY);
-        mDriftUncertaintyNanosPerSecond = Double.NaN;
-    }
-
     public static final Creator<GnssClock> CREATOR = new Creator<GnssClock>() {
         @Override
         public GnssClock createFromParcel(Parcel parcel) {
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index d78ccee..761ee22 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -67,18 +67,21 @@
     public @interface MultipathIndicator {}
 
     /**
-     * The indicator is not available or it is unknown.
+     * The indicator is not available or the presence or absence of multipath is unknown.
      */
     public static final int MULTIPATH_INDICATOR_UNKNOWN = 0;
 
     /**
-     * The measurement has been indicated to use multi-path.
+     * The measurement shows signs of multi-path.
      */
     public static final int MULTIPATH_INDICATOR_DETECTED = 1;
 
     /**
-     * The measurement has been indicated not tu use multi-path.
+     * The measurement shows no signs of multi-path.
      */
+    public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2;
+
+    /** @removed */
     public static final int MULTIPATH_INDICATOR_NOT_USED = 2;
 
     /** This GNSS measurement's tracking state is invalid or unknown. */
@@ -192,15 +195,17 @@
     }
 
     /**
-     * Gets the Pseudo-random number (PRN).
-     * Range: [1, 32]
+     * Gets the satellite ID.
+     *
+     * <p>Interpretation depends on {@link #getConstellationType()}.
+     * See {@link GnssStatus#getSvid(int)}.
      */
     public int getSvid() {
         return mSvid;
     }
 
     /**
-     * Sets the Pseud-random number (PRN).
+     * Sets the Satellite ID.
      * @hide
      */
     @TestApi
@@ -209,7 +214,10 @@
     }
 
     /**
-     * Getst the constellation type.
+     * Gets the constellation type.
+     *
+     * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
+     * {@link GnssStatus}.
      */
     @GnssStatus.ConstellationType
     public int getConstellationType() {
@@ -228,13 +236,14 @@
     /**
      * Gets the time offset at which the measurement was taken in nanoseconds.
      *
-     * The reference receiver's time from which this is offset is specified by
+     * <p>The reference receiver's time from which this is offset is specified by
      * {@link GnssClock#getTimeNanos()}.
      *
-     * The sign of this value is given by the following equation:
-     *      measurement time = time_ns + time_offset_ns
+     * <p>The sign of this value is given by the following equation:
+     * <pre>
+     *      measurement time = TimeNanos + TimeOffsetNanos</pre>
      *
-     * The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
+     * <p>The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
      * accuracy.
      */
     public double getTimeOffsetNanos() {
@@ -252,9 +261,10 @@
 
     /**
      * Gets per-satellite sync state.
-     * It represents the current sync state for the associated satellite.
      *
-     * This value helps interpret {@link #getReceivedSvTimeNanos()}.
+     * <p>It represents the current sync state for the associated satellite.
+     *
+     * <p>This value helps interpret {@link #getReceivedSvTimeNanos()}.
      */
     public int getState() {
         return mState;
@@ -271,7 +281,8 @@
 
     /**
      * Gets a string representation of the 'sync state'.
-     * For internal and logging use only.
+     *
+     * <p>For internal and logging use only.
      */
     private String getStateString() {
         if (mState == STATE_UNKNOWN) {
@@ -335,66 +346,79 @@
     /**
      * Gets the received GNSS satellite time, at the measurement time, in nanoseconds.
      *
-     * For GPS &amp; QZSS, this is:
-     *   Received GPS Time-of-Week at the measurement time, in nanoseconds.
-     *   The value is relative to the beginning of the current GPS week.
+     * <p>For GPS &amp; QZSS, this is:
+     * <ul>
+     * <li>Received GPS Time-of-Week at the measurement time, in nanoseconds.</li>
+     * <li>The value is relative to the beginning of the current GPS week.</li>
+     * </ul>
      *
-     *   Given the highest sync state that can be achieved, per each satellite, valid range
-     *   for this field can be:
+     * <p>Given the highest sync state that can be achieved, per each satellite, valid range
+     * for this field can be:
+     * <pre>
      *     Searching       : [ 0       ]   : STATE_UNKNOWN
      *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
      *     Bit sync        : [ 0  20ms ]   : STATE_BIT_SYNC is set
      *     Subframe sync   : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
-     *     TOW decoded     : [ 0 1week ]   : STATE_TOW_DECODED is set
+     *     TOW decoded     : [ 0 1week ]   : STATE_TOW_DECODED is set</pre>
      *
-     *   Note well: if there is any ambiguity in integer millisecond,
-     *   STATE_MSEC_AMBIGUOUS should be set accordingly, in the 'state' field.
+     * <p>Note well: if there is any ambiguity in integer millisecond, {@code STATE_MSEC_AMBIGUOUS}
+     * should be set accordingly, in the 'state' field.
      *
-     *   This value must be populated if 'state' != STATE_UNKNOWN.
+     * <p>This value must be populated if 'state' != {@code STATE_UNKNOWN}.
      *
-     * For Glonass, this is:
-     *   Received Glonass time of day, at the measurement time in nanoseconds.
+     * <p>For Glonass, this is:
+     * <ul>
+     * <li>Received Glonass time of day, at the measurement time in nanoseconds.</li>
+     * </ul>
      *
-     *   Given the highest sync state that can be achieved, per each satellite, valid range for
-     *   this field can be:
+     * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
+     * this field can be:
+     * <pre>
      *     Searching       : [ 0       ]   : STATE_UNKNOWN
      *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
-     *    Symbol sync    : [ 0  10ms ]   : STATE_SYMBOL_SYNC is set
-     *    Bit sync       : [ 0  20ms ]   : STATE_BIT_SYNC is set
-     *     String sync     : [ 0    2s ]   :  STATE_GLO_STRING_SYNC is set
-     *    Time of day      : [ 0  1day ]   : STATE_GLO_TOD_DECODED is set
+     *     Symbol sync     : [ 0  10ms ]   : STATE_SYMBOL_SYNC is set
+     *     Bit sync        : [ 0  20ms ]   : STATE_BIT_SYNC is set
+     *     String sync     : [ 0    2s ]   : STATE_GLO_STRING_SYNC is set
+     *     Time of day     : [ 0  1day ]   : STATE_GLO_TOD_DECODED is set</pre>
      *
-     * For Beidou, this is:
-     *   Received Beidou time of week, at the measurement time in nanoseconds.
+     * <p>For Beidou, this is:
+     * <ul>
+     * <li>Received Beidou time of week, at the measurement time in nanoseconds.</li>
+     * </ul>
      *
-     *   Given the highest sync state that can be achieved, per each satellite, valid range for
-     *   this field can be:
+     * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
+     * this field can be:
+     * <pre>
      *     Searching       : [ 0       ]   : STATE_UNKNOWN
      *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
      *     Bit sync (D2)   : [ 0   2ms ]   : STATE_BDS_D2_BIT_SYNC is set
      *     Bit sync (D1)   : [ 0  20ms ]   : STATE_BIT_SYNC is set
      *     Subframe (D2)   : [ 0  0.6s ]   : STATE_BDS_D2_SUBFRAME_SYNC is set
      *     Subframe (D1)   : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
-     *     Time of week    : [ 0 1week ]   : STATE_TOW_DECODED is set
+     *     Time of week    : [ 0 1week ]   : STATE_TOW_DECODED is set</pre>
      *
-     * For Galileo, this is:
-     *   Received Galileo time of week, at the measurement time in nanoseconds.
+     * <p>For Galileo, this is:
+     * <ul>
+     * <li>Received Galileo time of week, at the measurement time in nanoseconds.</li>
+     * </ul>
+     * <pre>
+     *     E1BC code lock   : [ 0   4ms ]  : STATE_GAL_E1BC_CODE_LOCK is set
+     *     E1C 2nd code lock: [ 0 100ms ]  : STATE_GAL_E1C_2ND_CODE_LOCK is set
+     *     E1B page         : [ 0    2s ]  : STATE_GAL_E1B_PAGE_SYNC is set
+     *     Time of week     : [ 0 1week ]  : STATE_GAL_TOW_DECODED is set</pre>
      *
-     *     E1BC code lock  : [ 0   4ms ]   : STATE_GAL_E1BC_CODE_LOCK is set
-     *     E1C 2nd code lock : [ 0   100ms ]   : STATE_GAL_E1C_2ND_CODE_LOCK is set
+     * <p>For SBAS, this is:
+     * <ul>
+     * <li>Received SBAS time, at the measurement time in nanoseconds.</li>
+     * </ul>
      *
-     *     E1B page        : [ 0    2s ]   : STATE_GAL_E1B_PAGE_SYNC is set
-     *     Time of week    : [ 0 1week ]   : STATE_GAL_TOW_DECODED is set
-     *
-     *   For SBAS, this is:
-     *     Received SBAS time, at the measurement time in nanoseconds.
-     *
-     *   Given the highest sync state that can be achieved, per each satellite, valid range for
-     *   this field can be:
+     * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
+     * this field can be:
+     * <pre>
      *     Searching       : [ 0       ]   : STATE_UNKNOWN
      *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
      *     Symbol sync     : [ 0   2ms ]   : STATE_SYMBOL_SYNC is set
-     *     Message         : [ 0    1s ]   : STATE_SBAS_SYNC is set
+     *     Message         : [ 0    1s ]   : STATE_SBAS_SYNC is set</pre>
      */
     public long getReceivedSvTimeNanos() {
         return mReceivedSvTimeNanos;
@@ -410,7 +434,7 @@
     }
 
     /**
-     * Gets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
+     * Gets the error estimate (1-sigma) for the received GNSS time, in nanoseconds.
      */
     public long getReceivedSvTimeUncertaintyNanos() {
         return mReceivedSvTimeUncertaintyNanos;
@@ -427,9 +451,10 @@
 
     /**
      * Gets the Carrier-to-noise density in dB-Hz.
-     * Range: [0, 63].
      *
-     * The value contains the measured C/N0 for the signal at the antenna input.
+     * <p>Typical range: 10-50 db-Hz.
+     *
+     * <p>The value contains the measured C/N0 for the signal at the antenna input.
      */
     public double getCn0DbHz() {
         return mCn0DbHz;
@@ -447,16 +472,18 @@
     /**
      * Gets the Pseudorange rate at the timestamp in m/s.
      *
-     * The reported value includes {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
+     * <p>The error estimate for this value is
+     * {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
      *
-     * The value is uncorrected, hence corrections for receiver and satellite clock frequency errors
-     * should not be included.
+     * <p>The value is uncorrected, i.e. corrections for receiver and satellite clock frequency
+     * errors are not included.
      *
-     * A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
+     * <p>A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
      * sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler shift'
      * is given by the equation:
      *
-     *      pseudorange rate = -k * doppler shift   (where k is a constant)
+     * <pre>
+     *      pseudorange rate = -k * doppler shift   (where k is a constant)</pre>
      */
     public double getPseudorangeRateMetersPerSecond() {
         return mPseudorangeRateMetersPerSecond;
@@ -473,7 +500,8 @@
 
     /**
      * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
-     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * <p>The uncertainty is represented as an absolute (single sided) value.
      */
     public double getPseudorangeRateUncertaintyMetersPerSecond() {
         return mPseudorangeRateUncertaintyMetersPerSecond;
@@ -490,7 +518,8 @@
 
     /**
      * Gets 'Accumulated Delta Range' state.
-     * It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
+     *
+     * <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
      * cycle slip (indicating 'loss of lock').
      */
     public int getAccumulatedDeltaRangeState() {
@@ -508,7 +537,8 @@
 
     /**
      * Gets a string representation of the 'Accumulated Delta Range state'.
-     * For internal and logging use only.
+     *
+     * <p>For internal and logging use only.
      */
     private String getAccumulatedDeltaRangeStateString() {
         if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
@@ -536,14 +566,17 @@
 
     /**
      * Gets the accumulated delta range since the last channel reset, in meters.
-     * The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
      *
-     * The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     * <p>The error estimate for this value is {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
      *
-     * A positive value indicates that the SV is moving away from the receiver.
+     * <p>The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     *
+     * <p>A positive value indicates that the SV is moving away from the receiver.
      * The sign of {@link #getAccumulatedDeltaRangeMeters()} and its relation to the sign of
      * {@link #getCarrierPhase()} is given by the equation:
-     *          accumulated delta range = -k * carrier phase    (where k is a constant)
+     *
+     * <pre>
+     *          accumulated delta range = -k * carrier phase    (where k is a constant)</pre>
      */
     public double getAccumulatedDeltaRangeMeters() {
         return mAccumulatedDeltaRangeMeters;
@@ -560,9 +593,10 @@
 
     /**
      * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
-     * The uncertainty is represented as an absolute (single sided) value.
      *
-     * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     * <p>The uncertainty is represented as an absolute (single sided) value.
+     *
+     * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
      */
     public double getAccumulatedDeltaRangeUncertaintyMeters() {
         return mAccumulatedDeltaRangeUncertaintyMeters;
@@ -571,7 +605,7 @@
     /**
      * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
      *
-     * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
      *
      * @hide
      */
@@ -581,17 +615,20 @@
     }
 
     /**
-     * Returns true if {@link #getCarrierFrequencyHz()} is available, false otherwise.
+     * Returns {@code true} if {@link #getCarrierFrequencyHz()} is available, {@code false}
+     * otherwise.
      */
     public boolean hasCarrierFrequencyHz() {
         return isFlagSet(HAS_CARRIER_FREQUENCY);
     }
 
     /**
-     * Gets the carrier frequency at which codes and messages are modulated, it can be L1 or L2.
-     * If the field is not set, the carrier frequency corresponds to L1.
+     * Gets the carrier frequency at which codes and messages are modulated.
      *
-     * The value is only available if {@link #hasCarrierFrequencyHz()} is true.
+     * <p>For GPS, e.g., it can be L1 or L2.  If the field is not set, it is the primary common use
+     * frequency, e.g. L1 for GPS.
+     *
+     * <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
      */
     public float getCarrierFrequencyHz() {
         return mCarrierFrequencyHz;
@@ -618,7 +655,7 @@
     }
 
     /**
-     * Returns true if {@link #getCarrierCycles()} is available, false otherwise.
+     * Returns {@code true} if {@link #getCarrierCycles()} is available, {@code false} otherwise.
      */
     public boolean hasCarrierCycles() {
         return isFlagSet(HAS_CARRIER_CYCLES);
@@ -626,9 +663,10 @@
 
     /**
      * The number of full carrier cycles between the satellite and the receiver.
-     * The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
      *
-     * The value is only available if {@link #hasCarrierCycles()} is true.
+     * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
+     *
+     * <p>The value is only available if {@link #hasCarrierCycles()} is {@code true}.
      */
     public long getCarrierCycles() {
         return mCarrierCycles;
@@ -655,7 +693,7 @@
     }
 
     /**
-     * Returns true if {@link #getCarrierPhase()} is available, false otherwise.
+     * Returns {@code true} if {@link #getCarrierPhase()} is available, {@code false} otherwise.
      */
     public boolean hasCarrierPhase() {
         return isFlagSet(HAS_CARRIER_PHASE);
@@ -663,13 +701,16 @@
 
     /**
      * Gets the RF phase detected by the receiver.
-     * Range: [0.0, 1.0].
-     * This is usually the fractional part of the complete carrier phase measurement.
      *
-     * The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
-     * The reported carrier-phase includes {@link #getCarrierPhaseUncertainty()}.
+     * <p>Range: [0.0, 1.0].
      *
-     * The value is only available if {@link #hasCarrierPhase()} is true.
+     * <p>This is the fractional part of the complete carrier phase measurement.
+     *
+     * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
+     *
+     * <p>The error estimate for this value is {@link #getCarrierPhaseUncertainty()}.
+     *
+     * <p>The value is only available if {@link #hasCarrierPhase()} is {@code true}.
      */
     public double getCarrierPhase() {
         return mCarrierPhase;
@@ -696,7 +737,8 @@
     }
 
     /**
-     * Returns true if {@link #getCarrierPhaseUncertainty()} is available, false otherwise.
+     * Returns {@code true} if {@link #getCarrierPhaseUncertainty()} is available, {@code false}
+     * otherwise.
      */
     public boolean hasCarrierPhaseUncertainty() {
         return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
@@ -704,9 +746,10 @@
 
     /**
      * Gets the carrier-phase's uncertainty (1-Sigma).
-     * The uncertainty is represented as an absolute (single sided) value.
      *
-     * The value is only available if {@link #hasCarrierPhaseUncertainty()} is true.
+     * <p>The uncertainty is represented as an absolute (single sided) value.
+     *
+     * <p>The value is only available if {@link #hasCarrierPhaseUncertainty()} is {@code true}.
      */
     public double getCarrierPhaseUncertainty() {
         return mCarrierPhaseUncertainty;
@@ -751,7 +794,8 @@
 
     /**
      * Gets a string representation of the 'multi-path indicator'.
-     * For internal and logging use only.
+     *
+     * <p>For internal and logging use only.
      */
     private String getMultipathIndicatorString() {
         switch(mMultipathIndicator) {
@@ -767,7 +811,7 @@
     }
 
     /**
-     * Returns true if {@link #getSnrInDb()} is available, false otherwise.
+     * Returns {@code true} if {@link #getSnrInDb()} is available, {@code false} otherwise.
      */
     public boolean hasSnrInDb() {
         return isFlagSet(HAS_SNR);
@@ -776,7 +820,7 @@
     /**
      * Gets the Signal-to-Noise ratio (SNR) in dB.
      *
-     * The value is only available if {@link #hasSnrInDb()} is true.
+     * <p>The value is only available if {@link #hasSnrInDb()} is {@code true}.
      */
     public double getSnrInDb() {
         return mSnrInDb;
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index ec252a8..3151694 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -16,6 +16,7 @@
 
 package android.location;
 
+import android.annotation.TestApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.os.Parcel;
@@ -33,29 +34,11 @@
  * Events are delivered to registered instances of {@link Callback}.
  */
 public final class GnssMeasurementsEvent implements Parcelable {
-    /**
-     * The status of the GNSS measurements event.
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GNSS_LOCATION_DISABLED})
-    public @interface GnssMeasurementsStatus {}
-
-    /**
-     * The system does not support tracking of GNSS Measurements. This status will not change in the
-     * future.
-     */
+    /** @removed */
     public static final int STATUS_NOT_SUPPORTED = 0;
-
-    /**
-     * GNSS Measurements are successfully being tracked, it will receive updates once they are
-     * available.
-     */
+    /** @removed */
     public static final int STATUS_READY = 1;
-
-    /**
-     * GNSS provider or Location is disabled, updates will not be received until they are enabled.
-     */
+    /** @removed */
     public static final int STATUS_GNSS_LOCATION_DISABLED = 2;
 
     private final GnssClock mClock;
@@ -68,6 +51,32 @@
      * {@link LocationManager#registerGnssMeasurementsCallback}.
      */
     public static abstract class Callback {
+        /**
+         * The status of the GNSS measurements event.
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED})
+        public @interface GnssMeasurementsStatus {}
+
+        /**
+         * The system does not support tracking of GNSS Measurements.
+         *
+         * <p>This status will not change in the future.
+         */
+        public static final int STATUS_NOT_SUPPORTED = 0;
+
+        /**
+         * GNSS Measurements are successfully being tracked, it will receive updates once they are
+         * available.
+         */
+        public static final int STATUS_READY = 1;
+
+        /**
+         * GPS provider or Location is disabled, updates will not be received until they are
+         * enabled.
+         */
+        public static final int STATUS_LOCATION_DISABLED = 2;
 
         /**
          * Reports the latest collected GNSS Measurements.
@@ -80,6 +89,10 @@
         public void onStatusChanged(@GnssMeasurementsStatus int status) {}
     }
 
+    /**
+     * @hide
+     */
+    @TestApi
     public GnssMeasurementsEvent(GnssClock clock, GnssMeasurement[] measurements) {
         if (clock == null) {
             throw new InvalidParameterException("Parameter 'clock' must not be null.");
@@ -94,6 +107,10 @@
         mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
     }
 
+    /**
+     * Gets the GNSS receiver clock information associated with the measurements for the current
+     * event.
+     */
     @NonNull
     public GnssClock getClock() {
         return mClock;
diff --git a/location/java/android/location/GnssNavigationMessage.aidl b/location/java/android/location/GnssNavigationMessage.aidl
new file mode 100644
index 0000000..1cdd510
--- /dev/null
+++ b/location/java/android/location/GnssNavigationMessage.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016, 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.location;
+
+parcelable GnssNavigationMessage;
diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java
index a5eace8..aa26111 100644
--- a/location/java/android/location/GnssNavigationMessage.java
+++ b/location/java/android/location/GnssNavigationMessage.java
@@ -34,7 +34,7 @@
     private static final byte[] EMPTY_ARRAY = new byte[0];
 
     /**
-     * The type of the GPS Clock.
+     * The type of the GNSS Navigation Message
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
@@ -81,6 +81,51 @@
      */
     public static final int STATUS_PARITY_REBUILT = (1<<1);
 
+    /**
+     * Used for receiving GNSS satellite Navigation Messages from the GNSS engine.
+     *
+     * <p>You can implement this interface and call
+     * {@link LocationManager#registerGnssNavigationMessageCallback}.
+     */
+    public static abstract class Callback {
+        /**
+         * The status of GNSS measurements event.
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED})
+        public @interface GnssNavigationMessageStatus {}
+
+        /**
+         * The system does not support tracking of GNSS Navigation Messages.
+         *
+         * This status will not change in the future.
+         */
+        public static final int STATUS_NOT_SUPPORTED = 0;
+
+        /**
+         * GNSS Navigation Messages are successfully being tracked, it will receive updates once
+         * they are available.
+         */
+        public static final int STATUS_READY = 1;
+
+        /**
+         * GNSS provider or Location is disabled, updated will not be received until they are
+         * enabled.
+         */
+        public static final int STATUS_LOCATION_DISABLED = 2;
+
+        /**
+         * Returns the latest collected GNSS Navigation Message.
+         */
+        public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {}
+
+        /**
+         * Returns the latest status of the GNSS Navigation Messages sub-system.
+         */
+        public void onStatusChanged(@GnssNavigationMessageStatus int status) {}
+    }
+
     // End enumerations in sync with gps.h
 
     private int mType;
@@ -170,15 +215,16 @@
     }
 
     /**
-     * Gets the Pseudo-random number.
-     * Range: [1, 32].
+     * Gets the satellite ID.
+     *
+     * <p>Range varies by constellation.  See definition at {@code GnssStatus#getSvid(int)}
      */
     public int getSvid() {
         return mSvid;
     }
 
     /**
-     * Sets the Pseud-random number.
+     * Sets the satellite ID.
      * @hide
      */
     @TestApi
@@ -187,10 +233,25 @@
     }
 
     /**
-     * Gets the Message Identifier.
-     * It provides an index so the complete Navigation Message can be assembled. i.e. for L1 C/A
-     * subframe 4 and 5, this value corresponds to the 'frame id' of the navigation message.
-     * Subframe 1, 2, 3 does not contain a 'frame id' and this might be reported as -1.
+     * Gets the Message identifier.
+     *
+     * <p>This provides an index to help with complete Navigation Message assembly. Similar
+     * identifiers within the data bits themselves often supplement this information, in ways even
+     * more specific to each message type; see the relevant satellite constellation ICDs for
+     * details.
+     *
+     * <ul>
+     * <li> For GPS L1 C/A subframe 4 and 5, this value corresponds to the 'frame id' of the
+     * navigation message, in the range of 1-25 (Subframe 1, 2, 3 does not contain a 'frame id' and
+     * this value can be set to -1.)</li>
+     * <li> For Glonass L1 C/A, this refers to the frame ID, in the range of 1-5.</li>
+     * <li> For BeiDou D1, this refers to the frame number in the range of 1-24</li>
+     * <li> For Beidou D2, this refers to the frame number, in the range of 1-120</li>
+     * <li> For Galileo F/NAV nominal frame structure, this refers to the subframe number, in the
+     * range of 1-12</li>
+     * <li> For Galileo I/NAV nominal frame structure, this refers to the subframe number in the
+     * range of 1-24</li>
+     * </ul>
      */
     public int getMessageId() {
         return mMessageId;
@@ -206,10 +267,18 @@
     }
 
     /**
-     * Gets the Sub-message Identifier.
-     * If required by {@link #getType()}, this value contains a sub-index within the current message
-     * (or frame) that is being transmitted. i.e. for L1 C/A the sub-message identifier corresponds
-     * to the sub-frame Id of the navigation message.
+     * Gets the sub-message identifier, relevant to the {@link #getType()} of the message.
+     *
+     * <ul>
+     * <li> For GPS L1 C/A, BeiDou D1 &amp; BeiDou D2, the submessage id corresponds to the subframe
+     * number of the navigation message, in the range of 1-5.</li>
+     * <li>For Glonass L1 C/A, this refers to the String number, in the range from 1-15</li>
+     * <li>For Galileo F/NAV, this refers to the page type in the range 1-6</li>
+     * <li>For Galileo I/NAV, this refers to the word type in the range 1-10+</li>
+     * <li>For Galileo in particular, the type information embedded within the data bits may be even
+     * more useful in interpretation, than the nominal page and word types provided in this
+     * field.</li>
+     * </ul>
      */
     public int getSubmessageId() {
         return mSubmessageId;
@@ -225,8 +294,25 @@
     }
 
     /**
-     * Gets the data associated with the Navigation Message.
-     * The bytes (or words) specified using big endian format (MSB first).
+     * Gets the data of the reported GPS message.
+     *
+     * <p>The bytes (or words) specified using big endian format (MSB first).
+     *
+     * <ul>
+     * <li>For GPS L1 C/A, Beidou D1 &amp; Beidou D2, each subframe contains 10 30-bit words. Each
+     * word (30 bits) should be fit into the last 30 bits in a 4-byte word (skip B31 and B32), with
+     * MSB first, for a total of 40 bytes, covering a time period of 6, 6, and 0.6 seconds,
+     * respectively.</li>
+     * <li>For Glonass L1 C/A, each string contains 85 data bits, including the checksum.  These
+     * bits should be fit into 11 bytes, with MSB first (skip B86-B88), covering a time period of 2
+     * seconds.</li>
+     * <li>For Galileo F/NAV, each word consists of 238-bit (sync &amp; tail symbols excluded). Each
+     * word should be fit into 30-bytes, with MSB first (skip B239, B240), covering a time period of
+     * 10 seconds.</li>
+     * <li>For Galileo I/NAV, each page contains 2 page parts, even and odd, with a total of 2x114 =
+     * 228 bits, (sync &amp; tail excluded) that should be fit into 29 bytes, with MSB first (skip
+     * B229-B232).</li>
+     * </ul>
      */
     @NonNull
     public byte[] getData() {
diff --git a/location/java/android/location/GnssNavigationMessageCallbackTransport.java b/location/java/android/location/GnssNavigationMessageCallbackTransport.java
index 4204b99..1eafd02 100644
--- a/location/java/android/location/GnssNavigationMessageCallbackTransport.java
+++ b/location/java/android/location/GnssNavigationMessageCallbackTransport.java
@@ -20,12 +20,12 @@
 import android.os.RemoteException;
 
 /**
- * A handler class to manage transport callback for {@link GnssNavigationMessageEvent.Callback}.
+ * A handler class to manage transport callback for {@link GnssNavigationMessage.Callback}.
  *
  * @hide
  */
 class GnssNavigationMessageCallbackTransport
-        extends LocalListenerHelper<GnssNavigationMessageEvent.Callback> {
+        extends LocalListenerHelper<GnssNavigationMessage.Callback> {
     private final ILocationManager mLocationManager;
 
     private final IGnssNavigationMessageListener mListenerTransport = new ListenerTransport();
@@ -51,11 +51,11 @@
 
     private class ListenerTransport extends IGnssNavigationMessageListener.Stub {
         @Override
-        public void onGnssNavigationMessageReceived(final GnssNavigationMessageEvent event) {
-            ListenerOperation<GnssNavigationMessageEvent.Callback> operation =
-                    new ListenerOperation<GnssNavigationMessageEvent.Callback>() {
+        public void onGnssNavigationMessageReceived(final GnssNavigationMessage event) {
+            ListenerOperation<GnssNavigationMessage.Callback> operation =
+                    new ListenerOperation<GnssNavigationMessage.Callback>() {
                 @Override
-                public void execute(GnssNavigationMessageEvent.Callback callback)
+                public void execute(GnssNavigationMessage.Callback callback)
                         throws RemoteException {
                     callback.onGnssNavigationMessageReceived(event);
                 }
@@ -65,10 +65,10 @@
 
         @Override
         public void onStatusChanged(final int status) {
-            ListenerOperation<GnssNavigationMessageEvent.Callback> operation =
-                    new ListenerOperation<GnssNavigationMessageEvent.Callback>() {
+            ListenerOperation<GnssNavigationMessage.Callback> operation =
+                    new ListenerOperation<GnssNavigationMessage.Callback>() {
                 @Override
-                public void execute(GnssNavigationMessageEvent.Callback callback)
+                public void execute(GnssNavigationMessage.Callback callback)
                         throws RemoteException {
                     callback.onStatusChanged(status);
                 }
diff --git a/location/java/android/location/GnssNavigationMessageEvent.java b/location/java/android/location/GnssNavigationMessageEvent.java
index 992dfc3..f7e5665 100644
--- a/location/java/android/location/GnssNavigationMessageEvent.java
+++ b/location/java/android/location/GnssNavigationMessageEvent.java
@@ -28,10 +28,11 @@
 /**
  * A class implementing a container for data associated with a navigation message event.
  * Events are delivered to registered instances of {@link Callback}.
+ * @removed
  */
 public final class GnssNavigationMessageEvent implements Parcelable {
     /**
-     * The status of GPS measurements event.
+     * The status of GNSS measurements event.
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
@@ -39,38 +40,40 @@
     public @interface GnssNavigationMessageStatus {}
 
     /**
-     * The system does not support tracking of GPS Navigation Messages. This status will not change
-     * in the future.
+     * The system does not support tracking of GNSS Navigation Messages.
+     *
+     * This status will not change in the future.
      */
     public static final int STATUS_NOT_SUPPORTED = 0;
 
     /**
-     * GPS Navigation Messages are successfully being tracked, it will receive updates once they are
-     * available.
+     * GNSS Navigation Messages are successfully being tracked, it will receive updates once they
+     * are available.
      */
     public static final int STATUS_READY = 1;
 
     /**
-     * GPS provider or Location is disabled, updated will not be received until they are enabled.
+     * GNSS provider or Location is disabled, updated will not be received until they are enabled.
      */
     public static final int STATUS_GNSS_LOCATION_DISABLED = 2;
 
     private final GnssNavigationMessage mNavigationMessage;
 
     /**
-     * Used for receiving GPS satellite Navigation Messages from the GPS engine.
-     * You can implement this interface and call
+     * Used for receiving GNSS satellite Navigation Messages from the GNSS engine.
+     *
+     * <p>You can implement this interface and call
      * {@link LocationManager#registerGnssNavigationMessageCallback}.
      */
     public static abstract class Callback {
 
         /**
-         * Returns the latest collected GPS Navigation Message.
+         * Returns the latest collected GNSS Navigation Message.
          */
         public void onGnssNavigationMessageReceived(GnssNavigationMessageEvent event) {}
 
         /**
-         * Returns the latest status of the GPS Navigation Messages sub-system.
+         * Returns the latest status of the GNSS Navigation Messages sub-system.
          */
         public void onStatusChanged(@GnssNavigationMessageStatus int status) {}
     }
diff --git a/location/java/android/location/GnssNmeaListener.java b/location/java/android/location/GnssNmeaListener.java
index 6c9b08a..756ae49 100644
--- a/location/java/android/location/GnssNmeaListener.java
+++ b/location/java/android/location/GnssNmeaListener.java
@@ -23,8 +23,9 @@
 * See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
 * You can implement this interface and call {@link LocationManager#addNmeaListener}
 * to receive NMEA data from the GNSS engine.
+* @removed
 */
 public interface GnssNmeaListener {
     /** Called when an NMEA message is received. */
     void onNmeaReceived(long timestamp, String nmea);
-}
\ No newline at end of file
+}
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index d76feec..e834c30 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -23,9 +23,11 @@
 
 /**
  * This class represents the current state of the GNSS engine.
- * This class is used in conjunction with the {@link GnssStatusCallback}.
+ * This class is used in conjunction with the {@link GnssStatus.Callback}.
  */
 public final class GnssStatus {
+    // these must match the definitions in gps.h
+
     /** Unknown constellation type. */
     public static final int CONSTELLATION_UNKNOWN = 0;
     /** Constellation type constant for GPS. */
@@ -41,16 +43,6 @@
     /** Constellation type constant for Galileo. */
     public static final int CONSTELLATION_GALILEO = 6;
 
-    /**
-     * Constellation type.
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
-            CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
-    public @interface ConstellationType {}
-
-    // these must match the definitions in gps.h
     /** @hide */
     public static final int GNSS_SV_FLAGS_NONE = 0;
     /** @hide */
@@ -67,6 +59,42 @@
     /** @hide */
     public static final int CONSTELLATION_TYPE_MASK = 0xf;
 
+    /**
+     * Used for receiving notifications when GNSS events happen.
+     */
+    public static abstract class Callback {
+        /**
+         * Called when GNSS system has started.
+         */
+        public void onStarted() {}
+
+        /**
+         * Called when GNSS system has stopped.
+         */
+        public void onStopped() {}
+
+        /**
+         * Called when the GNSS system has received its first fix since starting.
+         * @param ttffMillis the time from start to first fix in milliseconds.
+         */
+        public void onFirstFix(int ttffMillis) {}
+
+        /**
+         * Called periodically to report GNSS satellite status.
+         * @param status the current status of all satellites.
+         */
+        public void onSatelliteStatusChanged(GnssStatus status) {}
+    }
+
+    /**
+     * Constellation type.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
+            CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
+    public @interface ConstellationType {}
+
     /* These package private values are modified by the LocationManager class */
     /* package */ int[] mSvidWithFlags;
     /* package */ float[] mCn0DbHz;
@@ -83,15 +111,21 @@
         mAzimuths = azimuths;
     }
 
+    /** @removed */
+    public int getNumSatellites() {
+        return getSatelliteCount();
+    }
+
     /**
      * Gets the total number of satellites in satellite list.
      */
-    public int getNumSatellites() {
+    public int getSatelliteCount() {
         return mSvCount;
     }
 
     /**
-     * Retrieves the constellation type of the satellite at the specified position.
+     * Retrieves the constellation type of the satellite at the specified index.
+     *
      * @param satIndex the index of the satellite in the list.
      */
     @ConstellationType
@@ -101,7 +135,30 @@
     }
 
     /**
-     * Retrieves the pseudo-random number of the satellite at the specified position.
+     * Gets the identification number for the satellite at the specific index.
+     *
+     * <p>This svid is pseudo-random number for most constellations. It is FCN &amp; OSN number for
+     * Glonass.
+     *
+     * <p>The distinction is made by looking at constellation field
+     * {@link #getConstellationType(int)} Expected values are in the range of:
+     *
+     * <ul>
+     * <li>GPS: 1-32</li>
+     * <li>SBAS: 120-151, 183-192</li>
+     * <li>GLONASS:
+     * <ul>
+     *   <li>The least significant 8 bits, signed, are the orbital slot number (OSN) in the range
+     *   from 1-24, if known, or -127 if unknown</li>
+     *   <li>The next least signficant 8 bits, signed, are the frequency channel number (FCN) in the
+     *   range from -7 to +6, if known, and -127, if unknown</li>
+     *   <li>At least one of the two (FCN &amp; OSN) shall be set to a known value</li>
+     * </ul></li>
+     * <li>QZSS: 193-200</li>
+     * <li>Galileo: 1-36</li>
+     * <li>Beidou: 1-37</li>
+     * </ul>
+     *
      * @param satIndex the index of the satellite in the list.
      */
     public int getSvid(int satIndex) {
@@ -109,7 +166,9 @@
     }
 
     /**
-     * Retrieves the signal-noise ration of the satellite at the specified position.
+     * Retrieves the carrier-to-noise density at the antenna of the satellite at the specified index
+     * in dB-Hz.
+     *
      * @param satIndex the index of the satellite in the list.
      */
     public float getCn0DbHz(int satIndex) {
@@ -117,7 +176,8 @@
     }
 
     /**
-     * Retrieves the elevation of the satellite at the specified position.
+     * Retrieves the elevation of the satellite at the specified index.
+     *
      * @param satIndex the index of the satellite in the list.
      */
     public float getElevationDegrees(int satIndex) {
@@ -125,31 +185,46 @@
     }
 
     /**
-     * Retrieves the azimuth the satellite at the specified position.
+     * Retrieves the azimuth the satellite at the specified index.
+     *
      * @param satIndex the index of the satellite in the list.
      */
     public float getAzimuthDegrees(int satIndex) {
         return mAzimuths[satIndex];
     }
 
-    /**
-     * Detects whether the satellite at the specified position has ephemeris data.
-     * @param satIndex the index of the satellite in the list.
-     */
+    /** @removed */
     public boolean hasEphemeris(int satIndex) {
-        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+        return hasEphemerisData(satIndex);
     }
 
     /**
-     * Detects whether the satellite at the specified position has almanac data.
+     * Reports whether the satellite at the specified index has ephemeris data.
+     *
      * @param satIndex the index of the satellite in the list.
      */
+    public boolean hasEphemerisData(int satIndex) {
+        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+    }
+
+    /** @removed */
     public boolean hasAlmanac(int satIndex) {
+        return hasAlmanacData(satIndex);
+    }
+
+    /**
+     * Reports whether the satellite at the specified index has almanac data.
+     *
+     * @param satIndex the index of the satellite in the list.
+     */
+    public boolean hasAlmanacData(int satIndex) {
         return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
     }
 
     /**
-     * Detects whether the satellite at the specified position is used in fix.
+     * Reports whether the satellite at the specified index was used in the calculation of the most
+     * recent position fix.
+     *
      * @param satIndex the index of the satellite in the list.
      */
     public boolean usedInFix(int satIndex) {
diff --git a/location/java/android/location/GnssStatusCallback.java b/location/java/android/location/GnssStatusCallback.java
index 0d2955a..bf295ef 100644
--- a/location/java/android/location/GnssStatusCallback.java
+++ b/location/java/android/location/GnssStatusCallback.java
@@ -18,6 +18,7 @@
 
 /**
  * Used for receiving notifications when GNSS events happen.
+ * @removed
  */
 public abstract class GnssStatusCallback {
     /**
diff --git a/location/java/android/location/GpsSatellite.java b/location/java/android/location/GpsSatellite.java
index 820f5746..788d01e 100644
--- a/location/java/android/location/GpsSatellite.java
+++ b/location/java/android/location/GpsSatellite.java
@@ -18,8 +18,12 @@
 
 /**
  * This class represents the current state of a GPS satellite.
+ *
  * This class is used in conjunction with the {@link GpsStatus} class.
+ *
+ * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
  */
+@Deprecated
 public final class GpsSatellite {
     /* These package private values are modified by the GpsStatus class */
     boolean mValid;
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index bc518f9..038247b 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -24,8 +24,12 @@
 
 /**
  * This class represents the current state of the GPS engine.
- * This class is used in conjunction with the {@link Listener} interface.
+ *
+ * <p>This class is used in conjunction with the {@link Listener} interface.
+ *
+ * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
  */
+@Deprecated
 public final class GpsStatus {
     private static final int NUM_SATELLITES = 255;
 
@@ -102,7 +106,9 @@
 
     /**
      * Used for receiving notifications when GPS status has changed.
+     * @deprecated use {@link GnssStatus.Callback} instead.
      */
+    @Deprecated
     public interface Listener {
         /**
          * Called to report changes in the GPS status.
@@ -130,7 +136,9 @@
      * See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
      * You can implement this interface and call {@link LocationManager#addNmeaListener}
      * to receive NMEA data from the GPS engine.
+     * @deprecated use {@link OnNmeaMessageListener} instead.
      */
+    @Deprecated
     public interface NmeaListener {
         void onNmeaReceived(long timestamp, String nmea);
     }
diff --git a/location/java/android/location/IGnssNavigationMessageListener.aidl b/location/java/android/location/IGnssNavigationMessageListener.aidl
index de6129c..3e49b5b 100644
--- a/location/java/android/location/IGnssNavigationMessageListener.aidl
+++ b/location/java/android/location/IGnssNavigationMessageListener.aidl
@@ -16,12 +16,12 @@
 
 package android.location;
 
-import android.location.GnssNavigationMessageEvent;
+import android.location.GnssNavigationMessage;
 
 /**
  * {@hide}
  */
 oneway interface IGnssNavigationMessageListener {
-    void onGnssNavigationMessageReceived(in GnssNavigationMessageEvent event);
+    void onGnssNavigationMessageReceived(in GnssNavigationMessage event);
     void onStatusChanged(in int status);
 }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 28db099..b246360 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -70,10 +70,16 @@
             new HashMap<>();
     private final HashMap<GpsStatus.NmeaListener, GnssStatusListenerTransport> mGpsNmeaListeners =
             new HashMap<>();
-    private final HashMap<GnssStatusCallback, GnssStatusListenerTransport> mGnssStatusListeners =
+    private final HashMap<GnssStatusCallback, GnssStatusListenerTransport>
+            mOldGnssStatusListeners = new HashMap<>();
+    private final HashMap<GnssStatus.Callback, GnssStatusListenerTransport> mGnssStatusListeners =
             new HashMap<>();
-    private final HashMap<GnssNmeaListener, GnssStatusListenerTransport> mGnssNmeaListeners =
+    private final HashMap<GnssNmeaListener, GnssStatusListenerTransport> mOldGnssNmeaListeners =
             new HashMap<>();
+    private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
+            new HashMap<>();
+    private final HashMap<GnssNavigationMessageEvent.Callback, GnssNavigationMessage.Callback>
+            mNavigationMessageBridge = new HashMap<>();
     private GnssStatus mGnssStatus;
     private int mTimeToFirstFix;
 
@@ -1392,8 +1398,10 @@
 
         private final GpsStatus.Listener mGpsListener;
         private final GpsStatus.NmeaListener mGpsNmeaListener;
-        private final GnssStatusCallback mGnssCallback;
-        private final GnssNmeaListener mGnssNmeaListener;
+        private final GnssStatusCallback mOldGnssCallback;
+        private final GnssStatus.Callback mGnssCallback;
+        private final GnssNmeaListener mOldGnssNmeaListener;
+        private final OnNmeaMessageListener mGnssNmeaListener;
 
         private class GnssHandler extends Handler {
             public GnssHandler(Handler handler) {
@@ -1408,7 +1416,7 @@
                             int length = mNmeaBuffer.size();
                             for (int i = 0; i < length; i++) {
                                 Nmea nmea = mNmeaBuffer.get(i);
-                                mGnssNmeaListener.onNmeaReceived(nmea.mTimestamp, nmea.mNmea);
+                                mGnssNmeaListener.onNmeaMessage(nmea.mNmea, nmea.mTimestamp);
                             }
                             mNmeaBuffer.clear();
                         }
@@ -1456,7 +1464,8 @@
             mGnssHandler = new GnssHandler(handler);
             mGpsNmeaListener = null;
             mNmeaBuffer = null;
-            mGnssCallback = new GnssStatusCallback() {
+            mOldGnssCallback = null;
+            mGnssCallback = new GnssStatus.Callback() {
                 @Override
                 public void onStarted() {
                     mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
@@ -1477,6 +1486,7 @@
                     mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
                 }
             };
+            mOldGnssNmeaListener = null;
             mGnssNmeaListener = null;
         }
 
@@ -1489,10 +1499,12 @@
             mGnssHandler = new GnssHandler(handler);
             mGpsNmeaListener = listener;
             mNmeaBuffer = new ArrayList<Nmea>();
+            mOldGnssCallback = null;
             mGnssCallback = null;
-            mGnssNmeaListener = new GnssNmeaListener() {
+            mOldGnssNmeaListener = null;
+            mGnssNmeaListener = new OnNmeaMessageListener() {
                 @Override
-                public void onNmeaReceived(long timestamp, String nmea) {
+                public void onNmeaMessage(String nmea, long timestamp) {
                     mGpsNmeaListener.onNmeaReceived(timestamp, nmea);
                 }
             };
@@ -1503,8 +1515,45 @@
         }
 
         GnssStatusListenerTransport(GnssStatusCallback callback, Handler handler) {
+            mOldGnssCallback = callback;
+            mGnssCallback = new GnssStatus.Callback() {
+                @Override
+                public void onStarted() {
+                    mOldGnssCallback.onStarted();
+                }
+
+                @Override
+                public void onStopped() {
+                    mOldGnssCallback.onStopped();
+                }
+
+                @Override
+                public void onFirstFix(int ttff) {
+                    mOldGnssCallback.onFirstFix(ttff);
+                }
+
+                @Override
+                public void onSatelliteStatusChanged(GnssStatus status) {
+                    mOldGnssCallback.onSatelliteStatusChanged(status);
+                }
+            };
+            mGnssHandler = new GnssHandler(handler);
+            mOldGnssNmeaListener = null;
+            mGnssNmeaListener = null;
+            mNmeaBuffer = null;
+            mGpsListener = null;
+            mGpsNmeaListener = null;
+        }
+
+        GnssStatusListenerTransport(GnssStatus.Callback callback) {
+            this(callback, null);
+        }
+
+        GnssStatusListenerTransport(GnssStatus.Callback callback, Handler handler) {
+            mOldGnssCallback = null;
             mGnssCallback = callback;
             mGnssHandler = new GnssHandler(handler);
+            mOldGnssNmeaListener = null;
             mGnssNmeaListener = null;
             mNmeaBuffer = null;
             mGpsListener = null;
@@ -1517,7 +1566,29 @@
 
         GnssStatusListenerTransport(GnssNmeaListener listener, Handler handler) {
             mGnssCallback = null;
+            mOldGnssCallback = null;
             mGnssHandler = new GnssHandler(handler);
+            mOldGnssNmeaListener = listener;
+            mGnssNmeaListener = new OnNmeaMessageListener() {
+                @Override
+                public void onNmeaMessage(String message, long timestamp) {
+                    mOldGnssNmeaListener.onNmeaReceived(timestamp, message);
+                }
+            };
+            mGpsListener = null;
+            mGpsNmeaListener = null;
+            mNmeaBuffer = new ArrayList<Nmea>();
+        }
+
+        GnssStatusListenerTransport(OnNmeaMessageListener listener) {
+            this(listener, null);
+        }
+
+        GnssStatusListenerTransport(OnNmeaMessageListener listener, Handler handler) {
+            mOldGnssCallback = null;
+            mGnssCallback = null;
+            mGnssHandler = new GnssHandler(handler);
+            mOldGnssNmeaListener = null;
             mGnssNmeaListener = listener;
             mGpsListener = null;
             mGpsNmeaListener = null;
@@ -1589,7 +1660,7 @@
      * @return true if the listener was successfully added
      *
      * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
-     * @deprecated use {@link #registerGnssStatusCallback(GnssStatusCallback)} instead.
+     * @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead.
      */
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
@@ -1617,6 +1688,7 @@
      * Removes a GPS status listener.
      *
      * @param listener GPS status listener object to remove
+     * @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead.
      */
     @Deprecated
     public void removeGpsStatusListener(GpsStatus.Listener listener) {
@@ -1630,7 +1702,6 @@
         }
     }
 
-
     /**
      * Registers a GNSS status listener.
      *
@@ -1639,6 +1710,7 @@
      * @return true if the listener was successfully added
      *
      * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     * @removed
      */
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean registerGnssStatusCallback(GnssStatusCallback callback) {
@@ -1654,10 +1726,73 @@
      * @return true if the listener was successfully added
      *
      * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     * @removed
      */
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean registerGnssStatusCallback(GnssStatusCallback callback, Handler handler) {
         boolean result;
+        if (mOldGnssStatusListeners.get(callback) != null) {
+            // listener is already registered
+            return true;
+        }
+        try {
+            GnssStatusListenerTransport transport =
+                    new GnssStatusListenerTransport(callback, handler);
+            result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
+            if (result) {
+                mOldGnssStatusListeners.put(callback, transport);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        return result;
+    }
+
+    /**
+     * Removes a GNSS status listener.
+     *
+     * @param callback GNSS status listener object to remove
+     * @removed
+     */
+    public void unregisterGnssStatusCallback(GnssStatusCallback callback) {
+        try {
+            GnssStatusListenerTransport transport = mOldGnssStatusListeners.remove(callback);
+            if (transport != null) {
+                mService.unregisterGnssStatusCallback(transport);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers a GNSS status listener.
+     *
+     * @param callback GNSS status listener object to register
+     *
+     * @return true if the listener was successfully added
+     *
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssStatusCallback(GnssStatus.Callback callback) {
+        return registerGnssStatusCallback(callback, null);
+    }
+
+    /**
+     * Registers a GNSS status listener.
+     *
+     * @param callback GNSS status listener object to register
+     * @param handler the handler that the callback runs on.
+     *
+     * @return true if the listener was successfully added
+     *
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssStatusCallback(GnssStatus.Callback callback, Handler handler) {
+        boolean result;
         if (mGnssStatusListeners.get(callback) != null) {
             // listener is already registered
             return true;
@@ -1681,7 +1816,7 @@
      *
      * @param callback GNSS status listener object to remove
      */
-    public void unregisterGnssStatusCallback(GnssStatusCallback callback) {
+    public void unregisterGnssStatusCallback(GnssStatus.Callback callback) {
         try {
             GnssStatusListenerTransport transport = mGnssStatusListeners.remove(callback);
             if (transport != null) {
@@ -1700,7 +1835,7 @@
      * @return true if the listener was successfully added
      *
      * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
-     * @deprecated use {@link #addNmeaListener(GnssNmeaListener)} instead.
+     * @deprecated use {@link #addNmeaListener(OnNmeaMessageListener)} instead.
      */
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
@@ -1728,6 +1863,7 @@
      * Removes an NMEA listener.
      *
      * @param listener a {@link GpsStatus.NmeaListener} object to remove
+     * @deprecated use {@link #removeNmeaListener(OnNmeaMessageListener)} instead.
      */
     @Deprecated
     public void removeNmeaListener(GpsStatus.NmeaListener listener) {
@@ -1749,6 +1885,7 @@
      * @return true if the listener was successfully added
      *
      * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     * @removed
      */
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean addNmeaListener(GnssNmeaListener listener) {
@@ -1764,6 +1901,7 @@
      * @return true if the listener was successfully added
      *
      * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     * @removed
      */
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean addNmeaListener(GnssNmeaListener listener, Handler handler) {
@@ -1778,6 +1916,69 @@
                     new GnssStatusListenerTransport(listener, handler);
             result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
             if (result) {
+                mOldGnssNmeaListeners.put(listener, transport);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        return result;
+    }
+
+    /**
+     * Removes an NMEA listener.
+     *
+     * @param listener a {@link GnssNmeaListener} object to remove
+     * @removed
+     */
+    public void removeNmeaListener(GnssNmeaListener listener) {
+        try {
+            GnssStatusListenerTransport transport = mOldGnssNmeaListeners.remove(listener);
+            if (transport != null) {
+                mService.unregisterGnssStatusCallback(transport);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adds an NMEA listener.
+     *
+     * @param listener a {@link OnNmeaMessageListener} object to register
+     *
+     * @return true if the listener was successfully added
+     *
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean addNmeaListener(OnNmeaMessageListener listener) {
+        return addNmeaListener(listener, null);
+    }
+
+    /**
+     * Adds an NMEA listener.
+     *
+     * @param listener a {@link OnNmeaMessageListener} object to register
+     * @param handler the handler that the listener runs on.
+     *
+     * @return true if the listener was successfully added
+     *
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean addNmeaListener(OnNmeaMessageListener listener, Handler handler) {
+        boolean result;
+
+        if (mGpsNmeaListeners.get(listener) != null) {
+            // listener is already registered
+            return true;
+        }
+        try {
+            GnssStatusListenerTransport transport =
+                    new GnssStatusListenerTransport(listener, handler);
+            result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
+            if (result) {
                 mGnssNmeaListeners.put(listener, transport);
             }
         } catch (RemoteException e) {
@@ -1790,9 +1991,9 @@
     /**
      * Removes an NMEA listener.
      *
-     * @param listener a {@link GnssNmeaListener} object to remove
+     * @param listener a {@link OnNmeaMessageListener} object to remove
      */
-    public void removeNmeaListener(GnssNmeaListener listener) {
+    public void removeNmeaListener(OnNmeaMessageListener listener) {
         try {
             GnssStatusListenerTransport transport = mGnssNmeaListeners.remove(listener);
             if (transport != null) {
@@ -1843,7 +2044,8 @@
      * No-op method to keep backward-compatibility.
      * Don't use it. Use {@link #unregisterGnssMeasurementsCallback} instead.
      * @hide
-     * @deprecated
+     * @deprecated use {@link #unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback)}
+     * instead.
      */
     @Deprecated
     @SystemApi
@@ -1872,10 +2074,23 @@
     }
 
     /**
-     * Registers a GPS Navigation Message callback.
+     * No-op method to keep backward-compatibility.
+     * Don't use it. Use {@link #unregisterGnssNavigationMessageCallback} instead.
+     * @hide
+     * @deprecated use {@link #unregisterGnssNavigationMessageCallback(GnssMeasurements.Callback)}
+     * instead
+     */
+    @Deprecated
+    @SystemApi
+    public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
+    }
+
+    /**
+     * Registers a GNSS Navigation Message callback.
      *
      * @param callback a {@link GnssNavigationMessageEvent.Callback} object to register.
      * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     * @removed
      */
     public boolean registerGnssNavigationMessageCallback(
             GnssNavigationMessageEvent.Callback callback) {
@@ -1883,40 +2098,80 @@
     }
 
     /**
-     * Registers a GPS Navigation Message callback.
+     * Registers a GNSS Navigation Message callback.
      *
      * @param callback a {@link GnssNavigationMessageEvent.Callback} object to register.
      * @param handler the handler that the callback runs on.
      * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     * @removed
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssNavigationMessageCallback(
+            final GnssNavigationMessageEvent.Callback callback, Handler handler) {
+        GnssNavigationMessage.Callback bridge = new GnssNavigationMessage.Callback() {
+            @Override
+            public void onGnssNavigationMessageReceived(GnssNavigationMessage message) {
+                GnssNavigationMessageEvent event = new GnssNavigationMessageEvent(message);
+                callback.onGnssNavigationMessageReceived(event);
+            }
+
+            @Override
+            public void onStatusChanged(int status) {
+                callback.onStatusChanged(status);
+            }
+        };
+        mNavigationMessageBridge.put(callback, bridge);
+        return mGnssNavigationMessageCallbackTransport.add(bridge, handler);
+    }
+
+    /**
+     * Unregisters a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessageEvent.Callback} object to remove.
+     * @removed
+     */
+    public void unregisterGnssNavigationMessageCallback(
+            GnssNavigationMessageEvent.Callback callback) {
+        mGnssNavigationMessageCallbackTransport.remove(
+                mNavigationMessageBridge.remove(
+                        callback));
+    }
+
+    /**
+     * Registers a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     */
+    public boolean registerGnssNavigationMessageCallback(
+            GnssNavigationMessage.Callback callback) {
+        return registerGnssNavigationMessageCallback(callback, null);
+    }
+
+    /**
+     * Registers a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+     * @param handler the handler that the callback runs on.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
      */
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean registerGnssNavigationMessageCallback(
-            GnssNavigationMessageEvent.Callback callback, Handler handler) {
+            GnssNavigationMessage.Callback callback, Handler handler) {
         return mGnssNavigationMessageCallbackTransport.add(callback, handler);
     }
 
     /**
-     * Unregisters a GPS Navigation Message callback.
+     * Unregisters a GNSS Navigation Message callback.
      *
-     * @param callback a {@link GnssNavigationMessageEvent.Callback} object to remove.
+     * @param callback a {@link GnssNavigationMessage.Callback} object to remove.
      */
     public void unregisterGnssNavigationMessageCallback(
-            GnssNavigationMessageEvent.Callback callback) {
+            GnssNavigationMessage.Callback callback) {
         mGnssNavigationMessageCallbackTransport.remove(callback);
     }
 
     /**
-     * No-op method to keep backward-compatibility.
-     * Don't use it. Use {@link #unregisterGnssNavigationMessageCallback} instead.
-     * @hide
-     * @deprecated
-     */
-    @Deprecated
-    @SystemApi
-    public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
-    }
-
-    /**
      * Retrieves information about the current status of the GPS engine.
      * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged}
      * callback to ensure that the data is copied atomically.
diff --git a/location/java/android/location/OnNmeaMessageListener.java b/location/java/android/location/OnNmeaMessageListener.java
new file mode 100644
index 0000000..ccf6ce8
--- /dev/null
+++ b/location/java/android/location/OnNmeaMessageListener.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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.location;
+
+/**
+* Used for receiving NMEA sentences from the GNSS.
+* NMEA 0183 is a standard for communicating with marine electronic devices
+* and is a common method for receiving data from a GNSS, typically over a serial port.
+* See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
+* You can implement this interface and call {@link LocationManager#addNmeaListener}
+* to receive NMEA data from the GNSS engine.
+*/
+public interface OnNmeaMessageListener {
+    /**
+     * Called when an NMEA message is received.
+     * @param message NMEA message
+     * @param timestamp milliseconds since January 1, 1970.
+     */
+    void onNmeaMessage(String message, long timestamp);
+}
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index a5ff29f..2613376 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -158,7 +158,7 @@
      * <p>The application may supply the URI for a TV program for filling in program specific data
      * fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
      * A non-null {@code programHint} implies the started recording should be of that specific
-     * program, whereas null {@code programHint} does not impose such a requirement and the
+     * program, whereas null {@code programUri} does not impose such a requirement and the
      * recording can span across multiple TV programs. In either case, the application must call
      * {@link TvRecordingClient#stopRecording()} to stop the recording.
      *
diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java
index 3814630..61fbfb9 100644
--- a/media/java/android/mtp/MtpServer.java
+++ b/media/java/android/mtp/MtpServer.java
@@ -23,12 +23,14 @@
 public class MtpServer implements Runnable {
 
     private long mNativeContext; // accessed by native methods
+    private final MtpDatabase mDatabase;
 
     static {
         System.loadLibrary("media_jni");
     }
 
     public MtpServer(MtpDatabase database, boolean usePtp) {
+        mDatabase = database;
         native_setup(database, usePtp);
         database.setServer(this);
     }
@@ -42,6 +44,7 @@
     public void run() {
         native_run();
         native_cleanup();
+        mDatabase.close();
     }
 
     public void sendObjectAdded(int handle) {
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index 537b56d..d07942b 100644
--- a/media/jni/android_media_MediaDataSource.cpp
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -155,4 +155,8 @@
     return 0;
 }
 
+String8 JMediaDataSource::toString() {
+    return String8::format("JMediaDataSource(pid %d, uid %d)", getpid(), getuid());
+}
+
 }  // namespace android
diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h
index 34624eb..378baf4 100644
--- a/media/jni/android_media_MediaDataSource.h
+++ b/media/jni/android_media_MediaDataSource.h
@@ -46,6 +46,7 @@
     virtual status_t getSize(off64_t* size);
     virtual void close();
     virtual uint32_t getFlags();
+    virtual String8 toString();
 
 private:
     // Protect all member variables with mLock because this object will be
diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
index 6eea81b..7dba545 100644
--- a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
@@ -148,8 +148,9 @@
     protected void onDraw(Canvas canvas) {
         float totalDrawingWidth = getDrawingWidth();
         float currentDrawPosition;
-        if ((mGravity & Gravity.START) != 0) {
-            if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+        if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
+            if ((mGravity & Gravity.RELATIVE_LAYOUT_DIRECTION) != 0
+                    && getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
                 currentDrawPosition = getWidth() - getPaddingRight() - totalDrawingWidth;
             } else {
                 currentDrawPosition = getPaddingLeft();
@@ -163,7 +164,7 @@
         float yPosition =
                 (getHeight() - getPaddingBottom() - getPaddingTop()) / 2 + getPaddingTop();
         canvas.clipRect(getPaddingLeft(), getPaddingTop(),
-                getWidth()-getPaddingRight(), getHeight()-getPaddingBottom());
+                getWidth() - getPaddingRight(), getHeight() - getPaddingBottom());
         float charLength = bounds.right - bounds.left;
         for (int i = 0; i < length; i++) {
             CharState charState = mTextChars.get(i);
diff --git a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
index eb96015..7c8806e 100644
--- a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
+++ b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
 #define LOG_TAG "AppFuseJNI"
 #include "utils/Log.h"
 
@@ -451,7 +450,7 @@
     ScopedFd fd(static_cast<int>(jfd));
     AppFuse appfuse(env, self);
 
-    ALOGD("Start fuse loop.");
+    ALOGV("Start fuse loop.");
     while (true) {
         FuseRequest request;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 6052ccd..7f0e27a 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -399,6 +399,9 @@
         // Copy previous profile list into removedProfiles
         removedProfiles.clear();
         removedProfiles.addAll(profiles);
+        if (DEBUG) {
+            Log.d(TAG,"Current Profiles" + profiles.toString());
+        }
         profiles.clear();
 
         if (uuids == null) {
@@ -415,6 +418,13 @@
             }
         }
 
+        if ((mHfpClientProfile != null) &&
+                BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) &&
+                BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree)) {
+            profiles.add(mHfpClientProfile);
+            removedProfiles.remove(mHfpClientProfile);
+        }
+
         if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS) &&
             mA2dpProfile != null) {
             profiles.add(mA2dpProfile);
@@ -425,7 +435,7 @@
                 mA2dpSinkProfile != null) {
                 profiles.add(mA2dpSinkProfile);
                 removedProfiles.remove(mA2dpSinkProfile);
-            }
+        }
 
         if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush) &&
             mOppProfile != null) {
@@ -461,5 +471,9 @@
             profiles.remove(mPbapProfile);
             removedProfiles.add(mPbapProfile);
         }
+
+        if (DEBUG) {
+            Log.d(TAG,"New Profiles" + profiles.toString());
+        }
     }
 }
diff --git a/packages/SystemUI/res/layout/forced_resizable_activity.xml b/packages/SystemUI/res/layout/forced_resizable_activity.xml
index df245bc..9cf9f6e 100644
--- a/packages/SystemUI/res/layout/forced_resizable_activity.xml
+++ b/packages/SystemUI/res/layout/forced_resizable_activity.xml
@@ -22,6 +22,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
-        android:text="@string/forced_resizable_info_text"
+        android:text="@string/dock_forced_resizable"
         android:textColor="#ffffff"/>
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index b0dca9a..cce9c0f 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -26,9 +26,7 @@
             android:gravity="center_horizontal"
             android:minLines="2"
             android:padding="0dp"
-            android:fontFamily="sans-serif-condensed"
-            android:textStyle="normal"
-            android:textSize="@dimen/qs_tile_text_size"
+            android:textAppearance="@style/TextAppearance.QS.TileLabel"
             android:clickable="false" />
      <ImageView android:id="@+id/restricted_padlock"
             android:layout_width="@dimen/qs_tile_text_size"
diff --git a/packages/SystemUI/res/values/dimens_tv.xml b/packages/SystemUI/res/values/dimens_tv.xml
index 4e6a4b1..f536f86 100644
--- a/packages/SystemUI/res/values/dimens_tv.xml
+++ b/packages/SystemUI/res/values/dimens_tv.xml
@@ -57,4 +57,6 @@
     <!-- Extra space around the PIP control button icon to match with the focused circle -->
     <dimen name="tv_pip_button_icon_padding">5dp</dimen>
 
+    <!-- Values for entering Recents and exiting Recents -->
+    <dimen name="recents_tv_home_recents_shift">125dip</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/integers_tv.xml b/packages/SystemUI/res/values/integers_tv.xml
index 20cd330..6984d5a 100644
--- a/packages/SystemUI/res/values/integers_tv.xml
+++ b/packages/SystemUI/res/values/integers_tv.xml
@@ -17,5 +17,11 @@
     <integer name="item_scale_anim_duration">150</integer>
     <integer name="dismiss_short_duration">200</integer>
     <integer name="dismiss_long_duration">400</integer>
+
     <integer name="recents_tv_pip_focus_anim_duration">200</integer>
+
+    <!-- Duration for how long it takes cards to slide in or out when going to and from recents. -->
+    <integer name="recents_home_duration">400</integer>
+    <!-- Delay between the start of slide in animation for each card. -->
+    <integer name="recents_home_delay">40</integer>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 060e050..c536c1a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1557,9 +1557,6 @@
     <!-- Accessibility action for moving down the docked stack divider [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_divider_move_right">Move right</string>
 
-    <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity and that things might crash/not work properly [CHAR LIMIT=NONE] -->
-    <string name="forced_resizable_info_text">App may not work with multi-window</string>
-
     <!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
     <string name="accessibility_qs_edit_tile_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>, <xliff:g id="tile_name" example="Wi-Fi">%2$s</xliff:g>. Double tap to edit.</string>
 
@@ -1587,4 +1584,10 @@
     <!-- Accessibility label for window when QS editing is happening [CHAR LIMIT=NONE] -->
     <string name="accessibility_desc_quick_settings_edit">Quick settings editor.</string>
 
+    <!-- Multi-Window strings -->
+    <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity and that things might crash/not work properly [CHAR LIMIT=NONE] -->
+    <string name="dock_forced_resizable">App may not work with split-screen.</string>
+    <!-- Warning message when we try to dock a non-resizeble tasks and launch it in fullscreen instead. -->
+    <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 2b134af..5db35b1 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -180,6 +180,11 @@
         <item name="android:textColor">@color/data_usage_secondary</item>
     </style>
 
+    <style name="TextAppearance.QS.TileLabel">
+        <item name="android:textSize">@dimen/qs_tile_text_size</item>
+        <item name="android:fontFamily">sans-serif-condensed</item>
+    </style>
+
     <style name="BaseBrightnessDialogContainer">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index de8eec4..4d959d8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -157,7 +157,7 @@
         for (QSTile<?> tile : tiles) {
             QSTileBaseView tileView = mQsPanel.getTileView(tile);
             final TextView label = ((QSTileView) tileView).getLabel();
-            final View tileIcon = tileView.getIcon();
+            final View tileIcon = tileView.getIcon().getIconView();
             if (count < mNumQuickTiles && mAllowFancy) {
                 // Quick tiles.
                 QSTileBaseView quickTileView = mQuickQsPanel.getTileView(tile);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index 0af5fa6..e3a4909 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -47,10 +47,10 @@
     private final Rect mQsBounds = new Rect();
 
     private int mHeightOverride = -1;
-    private QSPanel mQSPanel;
+    protected QSPanel mQSPanel;
     private QSDetail mQSDetail;
     protected BaseStatusBarHeader mHeader;
-    private float mQsExpansion;
+    protected float mQsExpansion;
     private boolean mQsExpanded;
     private boolean mHeaderAnimating;
     private boolean mKeyguardShowing;
@@ -162,14 +162,18 @@
     }
 
     private void updateBottom() {
-        int heightOverride = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight();
-        int height = mQSCustomizer.isCustomizing() ? mQSCustomizer.getHeight()
-                : (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight()))
-                + mHeader.getCollapsedHeight();
+        int height = calculateContainerHeight();
         setBottom(getTop() + height);
         mQSDetail.setBottom(getTop() + height);
     }
 
+    protected int calculateContainerHeight() {
+        int heightOverride = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight();
+        return mQSCustomizer.isCustomizing() ? mQSCustomizer.getHeight()
+                : (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight()))
+                + mHeader.getCollapsedHeight();
+    }
+
     private void updateQsState() {
         boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating;
         mQSPanel.setExpanded(mQsExpanded);
@@ -302,4 +306,8 @@
             updateQsState();
         }
     };
+
+    public int getQsMinExpansionHeight() {
+        return mHeader.getHeight();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
index 546f8c3..6c224f7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
@@ -30,9 +30,9 @@
 
 public class QSIconView extends ViewGroup {
 
-    private final View mIcon;
-    private final int mIconSizePx;
-    private final int mTilePaddingBelowIconPx;
+    protected final View mIcon;
+    protected final int mIconSizePx;
+    protected final int mTilePaddingBelowIconPx;
     private boolean mAnimationEnabled = true;
 
     public QSIconView(Context context) {
@@ -50,6 +50,10 @@
         mAnimationEnabled = false;
     }
 
+    public View getIconView() {
+        return mIcon;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         final int w = MeasureSpec.getSize(widthMeasureSpec);
@@ -109,11 +113,11 @@
         return icon;
     }
 
-    protected static int exactly(int size) {
+    protected final int exactly(int size) {
         return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
     }
 
-    protected static void layout(View child, int left, int top) {
+    protected final void layout(View child, int left, int top) {
         child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index a05818a..1149c59 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -85,20 +85,7 @@
                 R.layout.quick_settings_brightness_dialog, this, false);
         addView(mBrightnessView);
 
-        mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
-                R.layout.qs_paged_tile_layout, this, false);
-        addView((View) mTileLayout);
-        findViewById(android.R.id.edit).setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(final View v) {
-                mHost.startRunnableDismissingKeyguard(new Runnable() {
-                    @Override
-                    public void run() {
-                        showEdit(v);
-                    }
-                });
-            }
-        });
+        setupTileLayout();
 
         mFooter = new QSFooter(this, context);
         addView(mFooter.getView());
@@ -111,6 +98,14 @@
 
     }
 
+    protected void setupTileLayout() {
+        mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
+                R.layout.qs_paged_tile_layout, this, false);
+        addView((View) mTileLayout);
+        findViewById(android.R.id.edit).setOnClickListener(view ->
+                mHost.startRunnableDismissingKeyguard(() -> showEdit(view)));
+    }
+
     public boolean isShowingCustomize() {
         return mCustomizePanel != null && mCustomizePanel.isCustomizing();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 57a1a4a..c3766e8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -33,7 +33,6 @@
 /** View that represents a standard quick settings tile. **/
 public class QSTileView extends QSTileBaseView {
     protected final Context mContext;
-    private QSIconView mIconView;
     private final int mTileSpacingPx;
     private int mTilePaddingTopPx;
 
@@ -44,7 +43,6 @@
         super(context, icon);
 
         mContext = context;
-        mIconView = icon;
         final Resources res = context.getResources();
         mTileSpacingPx = res.getDimensionPixelSize(R.dimen.qs_tile_spacing);
 
@@ -82,13 +80,13 @@
     }
 
     protected void createLabel() {
-        final Resources res = mContext.getResources();
         View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null);
         mLabel = (TextView) view.findViewById(R.id.tile_label);
         mPadLock = (ImageView) view.findViewById(R.id.restricted_padlock);
         addView(view);
     }
 
+    @Override
     protected void handleStateChanged(QSTile.State state) {
         super.handleStateChanged(state);
         if (!Objects.equal(mLabel.getText(), state.label)) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 6969e25..1e3c458 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -19,9 +19,9 @@
     private static final String TAG = "TileLayout";
 
     protected int mColumns;
-    private int mCellWidth;
-    private int mCellHeight;
-    private int mCellMargin;
+    protected int mCellWidth;
+    protected int mCellHeight;
+    protected int mCellMargin;
 
     protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
     private int mCellMarginTop;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index aba05aa..fda340d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -17,6 +17,7 @@
 package com.android.systemui.recents;
 
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.view.View.MeasureSpec;
 
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
@@ -36,7 +37,6 @@
 import android.util.MutableBoolean;
 import android.view.AppTransitionAnimationSpec;
 import android.view.LayoutInflater;
-import android.view.View;
 import android.view.ViewConfiguration;
 
 import com.android.internal.logging.MetricsLogger;
@@ -45,7 +45,6 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.ForcedResizableEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
@@ -125,13 +124,6 @@
                 loader.loadTasks(mContext, plan, launchOpts);
             }
         }
-
-        @Override
-        public void onActivityForcedResizable(String packageName, int taskId) {
-            EventBus.getDefault().sendOntoMainThread(
-                    new ForcedResizableEvent(packageName, taskId));
-
-        }
     }
 
     protected static RecentsTaskLoadPlan sInstanceLoadPlan;
@@ -608,23 +600,25 @@
             mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
 
             Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
-            int taskViewWidth = taskViewBounds.width();
-            synchronized (mHeaderBarLock) {
-                if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
-                        mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
-                    mHeaderBar.measure(
-                        View.MeasureSpec.makeMeasureSpec(taskViewWidth, View.MeasureSpec.EXACTLY),
-                        View.MeasureSpec.makeMeasureSpec(mTaskBarHeight, View.MeasureSpec.EXACTLY));
+            if (!taskViewBounds.isEmpty()) {
+                int taskViewWidth = taskViewBounds.width();
+                synchronized (mHeaderBarLock) {
+                    if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
+                            mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
+                        mHeaderBar.measure(
+                                MeasureSpec.makeMeasureSpec(taskViewWidth, MeasureSpec.EXACTLY),
+                                MeasureSpec.makeMeasureSpec(mTaskBarHeight, MeasureSpec.EXACTLY));
+                    }
+                    mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
                 }
-                mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
-            }
 
-            // Update the transition bitmap to match the new header bar height
-            if (mThumbTransitionBitmapCache == null ||
-                    (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
-                    (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
-                mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
-                        mTaskBarHeight, Bitmap.Config.ARGB_8888);
+                // Update the transition bitmap to match the new header bar height
+                if (mThumbTransitionBitmapCache == null ||
+                        (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
+                        (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
+                    mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
+                            mTaskBarHeight, Bitmap.Config.ARGB_8888);
+                }
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
deleted file mode 100644
index cdcabf0..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Sent when recents received the information that an activity got forced resizable, and we need
- * to inform the user about that.
- */
-public class ForcedResizableEvent extends EventBus.Event {
-
-    public final String packageName;
-    public final int taskId;
-
-    public ForcedResizableEvent(String packageName, int taskId) {
-        this.packageName = packageName;
-        this.taskId = taskId;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 1a4b40f..2d5addb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -144,6 +144,7 @@
         public void onPinnedActivityRestartAttempt() { }
         public void onPinnedStackAnimationEnded() { }
         public void onActivityForcedResizable(String packageName, int taskId) { }
+        public void onActivityDismissingDockedStack() { }
     }
 
     /**
@@ -182,6 +183,11 @@
             mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, 0, packageName)
                     .sendToTarget();
         }
+
+        @Override
+        public void onActivityDismissingDockedStack() throws RemoteException {
+            mHandler.sendEmptyMessage(H.ON_ACTIVITY_DISMISSING_DOCKED_STACK);
+        }
     };
 
     /**
@@ -1091,6 +1097,7 @@
         private static final int ON_PINNED_ACTIVITY_RESTART_ATTEMPT = 3;
         private static final int ON_PINNED_STACK_ANIMATION_ENDED = 4;
         private static final int ON_ACTIVITY_FORCED_RESIZABLE = 5;
+        private static final int ON_ACTIVITY_DISMISSING_DOCKED_STACK = 6;
 
         @Override
         public void handleMessage(Message msg) {
@@ -1126,6 +1133,12 @@
                     }
                     break;
                 }
+                case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
+                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                        mTaskStackListeners.get(i).onActivityDismissingDockedStack();
+                    }
+                    break;
+                }
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index f9f851a..13e1a14 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -37,14 +37,12 @@
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
 import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
-import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
 import com.android.systemui.recents.events.ui.UserInteractionEvent;
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -53,7 +51,9 @@
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.tv.animations.HomeRecentsEnterExitAnimationHolder;
 import com.android.systemui.recents.tv.views.RecentsTvView;
+import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
 import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.tv.pip.PipManager;
@@ -76,11 +76,14 @@
     private RecentsPackageMonitor mPackageMonitor;
     private long mLastTabKeyEventTime;
     private boolean mIgnoreAltTabRelease;
+    private boolean mLaunchedFromHome;
 
     private RecentsTvView mRecentsView;
     private View mPipView;
     private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
+    private TaskStackHorizontalGridView mTaskStackHorizontalGridView;
     private FinishRecentsRunnable mFinishLaunchHomeRunnable;
+    private HomeRecentsEnterExitAnimationHolder mHomeRecentsEnterExitAnimationHolder;
 
     private final PipManager mPipManager = PipManager.getInstance();
     private final PipManager.Listener mPipListener = new PipManager.Listener() {
@@ -174,6 +177,7 @@
         if (!plan.hasTasks()) {
             loader.preloadTasks(plan, -1, launchState.launchedFromHome);
         }
+        mLaunchedFromHome = launchState.launchedFromHome;
         TaskStack stack = plan.getTaskStack();
         RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
         loadOpts.runningTaskId = launchState.launchedToTaskId;
@@ -187,7 +191,8 @@
         Collections.reverse(stackTasks);
         if (mTaskStackViewAdapter == null) {
             mTaskStackViewAdapter = new TaskStackHorizontalViewAdapter(stackTasks);
-            mRecentsView.setTaskStackViewAdapter(mTaskStackViewAdapter);
+            mTaskStackHorizontalGridView = mRecentsView
+                    .setTaskStackViewAdapter(mTaskStackViewAdapter);
         } else {
             mTaskStackViewAdapter.setNewStackTasks(stackTasks);
         }
@@ -229,17 +234,24 @@
     }
 
     void dismissRecentsToHome(boolean animateTaskViews) {
-        DismissRecentsToHomeAnimationStarted dismissEvent =
-                new DismissRecentsToHomeAnimationStarted(animateTaskViews);
-        dismissEvent.addPostAnimationCallback(mFinishLaunchHomeRunnable);
-        dismissEvent.addPostAnimationCallback(new Runnable() {
+        Runnable closeSystemWindows = new Runnable() {
             @Override
             public void run() {
                 Recents.getSystemServices().sendCloseSystemWindows(
                         BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
             }
-        });
-        EventBus.getDefault().send(dismissEvent);
+        };
+        DismissRecentsToHomeAnimationStarted dismissEvent =
+                new DismissRecentsToHomeAnimationStarted(animateTaskViews);
+        dismissEvent.addPostAnimationCallback(mFinishLaunchHomeRunnable);
+        dismissEvent.addPostAnimationCallback(closeSystemWindows);
+
+        if(mTaskStackHorizontalGridView.getChildCount() > 0) {
+            mHomeRecentsEnterExitAnimationHolder.startExitAnimation(dismissEvent);
+        } else {
+            closeSystemWindows.run();
+            mFinishLaunchHomeRunnable.run();
+        }
     }
 
     boolean dismissRecentsToHomeIfVisible(boolean animated) {
@@ -319,6 +331,19 @@
         // Update the recent tasks
         updateRecentsTasks();
 
+        mHomeRecentsEnterExitAnimationHolder = new HomeRecentsEnterExitAnimationHolder(
+                getApplicationContext(), mTaskStackHorizontalGridView);
+        if(mTaskStackHorizontalGridView != null &&
+                mTaskStackHorizontalGridView.getChildCount() > 0) {
+            if(mLaunchedFromHome) {
+                mHomeRecentsEnterExitAnimationHolder.setEnterFromHomeStartingAnimationValues();
+            } else {
+                mHomeRecentsEnterExitAnimationHolder.setEnterFromAppStartingAnimationValues();
+            }
+        } else {
+            mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
+        }
+
         // If this is a new instance from a configuration change, then we have to manually trigger
         // the enter animation state, or if recents was relaunched by AM, without going through
         // the normal mechanisms
@@ -340,6 +365,9 @@
     @Override
     public void onEnterAnimationComplete() {
         super.onEnterAnimationComplete();
+        if(mLaunchedFromHome) {
+            mHomeRecentsEnterExitAnimationHolder.startEnterAnimation();
+        }
         EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
     }
 
@@ -444,12 +472,6 @@
         }
     }
 
-    public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
-        EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(true));
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
-        mRecentsView.invalidate();
-    }
-
     public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         int launchToTaskId = launchState.launchedToTaskId;
@@ -489,6 +511,11 @@
     @Override
     public boolean onPreDraw() {
         mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
+        if(mLaunchedFromHome) {
+            mHomeRecentsEnterExitAnimationHolder.setEnterFromHomeStartingAnimationValues();
+        } else {
+            mHomeRecentsEnterExitAnimationHolder.setEnterFromAppStartingAnimationValues();
+        }
         // We post to make sure that this information is delivered after this traversals is
         // finished.
         mRecentsView.post(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index fb62aff..fd31872 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -25,15 +25,19 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 
+import com.android.systemui.SystemUIApplication;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.model.ThumbnailData;
 import com.android.systemui.recents.tv.views.TaskCardView;
+import com.android.systemui.statusbar.tv.TvStatusBar;
 
 public class RecentsTvImpl extends RecentsImpl{
     public final static String RECENTS_TV_ACTIVITY =
@@ -81,16 +85,7 @@
         }
 
         if (!useThumbnailTransition) {
-            // If there is no thumbnail transition, but is launching from home into recents, then
-            // use a quick home transition and do the animation from home
-            if (hasRecentTasks) {
-                ActivityOptions opts = getHomeTransitionActivityOptions();
-                startRecentsActivity(topTask, opts, true /* fromHome */, false /* fromThumbnail */);
-            } else {
-                // Otherwise we do the normal fade from an unknown source
-                ActivityOptions opts = getUnknownTransitionActivityOptions();
-                startRecentsActivity(topTask, opts, true /* fromHome */, false /* fromThumbnail */);
-            }
+            startRecentsActivity(topTask, null, true /* fromHome */, false /* fromThumbnail */);
         }
         mLastToggleTime = SystemClock.elapsedRealtime();
     }
@@ -124,14 +119,26 @@
      */
     private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
             ActivityManager.RunningTaskInfo topTask) {
-        Bitmap thumbnail = mThumbTransitionBitmapCache;
         Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext);
-        if (thumbnail != null) {
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        ThumbnailData thumbnailData = ssp.getTaskThumbnail(topTask.id);
+        if (thumbnailData.thumbnail != null) {
+            Bitmap thumbnail = Bitmap.createScaledBitmap(thumbnailData.thumbnail, rect.width(),
+                    rect.height(), false);
             return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
-                    null, (int) rect.left, (int) rect.top,
-                    (int) rect.width(), (int) rect.height(), mHandler, null);
+                    thumbnail, (int) rect.left, (int) rect.top, (int) rect.width(),
+                    (int) rect.height(), mHandler, null);
         }
         // If both the screenshot and thumbnail fails, then just fall back to the default transition
         return getUnknownTransitionActivityOptions();
     }
+
+    @Override
+    public void onVisibilityChanged(Context context, boolean visible) {
+        SystemUIApplication app = (SystemUIApplication) context;
+        TvStatusBar statusBar = app.getComponent(TvStatusBar.class);
+        if (statusBar != null) {
+            statusBar.updateRecentsVisibility(visible);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java
index 8996d0b..fbcfa97 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java
@@ -18,9 +18,8 @@
 
 import android.animation.Animator;
 import android.content.res.Resources;
-import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.view.View;
 import android.widget.LinearLayout;
+import com.android.systemui.Interpolators;
 import com.android.systemui.recents.tv.views.TaskCardView;
 
 import com.android.systemui.R;
@@ -28,7 +27,6 @@
 public class DismissAnimationsHolder {
     private LinearLayout mDismissArea;
     private LinearLayout mTaskCardView;
-    private FastOutSlowInInterpolator mFastOutSlowIn;
     private int mCardYDelta;
     private long mShortDuration;
     private long mLongDuration;
@@ -36,7 +34,6 @@
     public DismissAnimationsHolder(TaskCardView taskCardView) {
         mTaskCardView = (LinearLayout) taskCardView.findViewById(R.id.recents_tv_card);
         mDismissArea = (LinearLayout) taskCardView.findViewById(R.id.card_dismiss);
-        mFastOutSlowIn = new FastOutSlowInInterpolator();
 
         Resources res = taskCardView.getResources();
         mCardYDelta = res.getDimensionPixelOffset(R.dimen.recents_tv_dismiss_shift_down);
@@ -45,36 +42,42 @@
     }
 
     public void startEnterAnimation() {
-        mDismissArea.animate().setDuration(mShortDuration);
-        mDismissArea.animate().setInterpolator(mFastOutSlowIn);
-        mDismissArea.animate().alpha(1.0f);
+        mDismissArea.animate()
+                .setDuration(mShortDuration)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .alpha(1.0f);
 
-        mTaskCardView.animate().setDuration(mShortDuration);
-        mTaskCardView.animate().setInterpolator(mFastOutSlowIn);
-        mTaskCardView.animate().translationYBy(mCardYDelta);
-        mTaskCardView.animate().alpha(0.5f);
+        mTaskCardView.animate()
+                .setDuration(mShortDuration)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .translationYBy(mCardYDelta)
+                .alpha(0.5f);
     }
 
     public void startExitAnimation() {
-        mDismissArea.animate().setDuration(mShortDuration);
-        mDismissArea.animate().setInterpolator(mFastOutSlowIn);
-        mDismissArea.animate().alpha(0.0f);
+        mDismissArea.animate()
+                .setDuration(mShortDuration)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .alpha(0.0f);
 
-        mTaskCardView.animate().setDuration(mShortDuration);
-        mTaskCardView.animate().setInterpolator(mFastOutSlowIn);
-        mTaskCardView.animate().translationYBy(-mCardYDelta);
-        mTaskCardView.animate().alpha(1.0f);
+        mTaskCardView.animate()
+                .setDuration(mShortDuration)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .translationYBy(-mCardYDelta)
+                .alpha(1.0f);
     }
 
     public void startDismissAnimation(Animator.AnimatorListener listener) {
-        mDismissArea.animate().setDuration(mShortDuration);
-        mDismissArea.animate().setInterpolator(mFastOutSlowIn);
-        mDismissArea.animate().alpha(0.0f);
+        mDismissArea.animate()
+                .setDuration(mShortDuration)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .alpha(0.0f);
 
-        mTaskCardView.animate().setDuration(mLongDuration);
-        mTaskCardView.animate().setInterpolator(mFastOutSlowIn);
-        mTaskCardView.animate().translationYBy(mCardYDelta);
-        mTaskCardView.animate().alpha(0.0f);
-        mTaskCardView.animate().setListener(listener);
+        mTaskCardView.animate()
+                .setDuration(mLongDuration)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .translationYBy(mCardYDelta)
+                .alpha(0.0f)
+                .setListener(listener);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/HomeRecentsEnterExitAnimationHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/HomeRecentsEnterExitAnimationHolder.java
new file mode 100644
index 0000000..278de87
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/HomeRecentsEnterExitAnimationHolder.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.tv.animations;
+
+import android.content.Context;
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.tv.views.TaskCardView;
+import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
+
+
+public class HomeRecentsEnterExitAnimationHolder {
+
+    private Context mContext;
+    private TaskStackHorizontalGridView mGridView;
+    private long mDelay;
+    private int mDuration;
+    private int mTranslationX;
+
+    public HomeRecentsEnterExitAnimationHolder(Context context,
+            TaskStackHorizontalGridView gridView) {
+        mContext = context;
+        mGridView = gridView;
+        mTranslationX = mContext.getResources()
+                .getDimensionPixelSize(R.dimen.recents_tv_home_recents_shift);
+        mDelay = mContext.getResources().getInteger(R.integer.recents_home_delay);
+        mDuration =  mContext.getResources().getInteger(R.integer.recents_home_duration);
+    }
+
+    public void startEnterAnimation() {
+        for(int i = 0; i < mGridView.getChildCount(); i++) {
+            TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+            view.setTranslationX(-mTranslationX);
+            view.setAlpha(0.0f);
+            view.animate()
+                    .alpha(1.0f)
+                    .translationX(0)
+                    .setDuration(mDuration)
+                    .setStartDelay(mDelay * i)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        }
+    }
+
+    public void startExitAnimation(DismissRecentsToHomeAnimationStarted dismissEvent) {
+        for(int i = mGridView.getChildCount() - 1; i >= 0; i--) {
+            TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+            view.animate()
+                    .alpha(0.0f)
+                    .translationXBy(-mTranslationX)
+                    .setDuration(mDuration)
+                    .setStartDelay(mDelay * (mGridView.getChildCount() - 1 - i))
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+            if(i == 0) {
+                view.animate().setListener(dismissEvent.getAnimationTrigger()
+                        .decrementOnAnimationEnd());
+                dismissEvent.getAnimationTrigger().increment();
+            }
+        }
+    }
+
+    public void setEnterFromHomeStartingAnimationValues() {
+        for(int i = 0; i < mGridView.getChildCount(); i++) {
+            TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+            view.setTranslationX(-mTranslationX);
+            view.setAlpha(0.0f);
+        }
+    }
+
+    public void setEnterFromAppStartingAnimationValues() {
+        for(int i = 0; i < mGridView.getChildCount(); i++) {
+            TaskCardView view = (TaskCardView) mGridView.getChildAt(i);
+            view.setTranslationX(0);
+            view.setAlpha(1.0f);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
index a69f8a2..fb1127e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
@@ -16,8 +16,10 @@
 package com.android.systemui.recents.tv.views;
 
 import android.annotation.Nullable;
+import android.app.Activity;
 import android.app.ActivityOptions;
 import android.content.Context;
+import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
@@ -120,8 +122,10 @@
         }
         try {
             Rect taskRect = taskView.getFocusedThumbnailRect();
+            Bitmap thumbnail = Bitmap.createScaledBitmap(task.thumbnail, taskRect.width(),
+                    taskRect.height(), false);
             WindowManagerGlobal.getWindowManagerService()
-                    .overridePendingAppTransitionAspectScaledThumb(task.thumbnail, taskRect.left,
+                    .overridePendingAppTransitionAspectScaledThumb(thumbnail, taskRect.left,
                             taskRect.top, taskRect.width(), taskRect.height(), callback, true);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to override transition: " + e);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
index 9da8eed..53fdf62 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
@@ -18,7 +18,10 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Handler;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.RecyclerView;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowInsets;
@@ -32,15 +35,15 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.LaunchTvTaskEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
-
-import java.util.ArrayList;
-import java.util.List;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 
 /**
  * Top level layout of recents for TV. This will show the TaskStacks using a HorizontalGridView.
@@ -58,7 +61,7 @@
     private Rect mSystemInsets = new Rect();
     private RecentsTvTransitionHelper mTransitionHelper;
     private Handler mHandler;
-
+    private OnScrollListener mScrollListener;
     public RecentsTvView(Context context) {
         this(context, null);
     }
@@ -111,8 +114,7 @@
         if (mTaskStackHorizontalView != null) {
             Task task = mTaskStackHorizontalView.getFocusedTask();
             if (task != null) {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+                launchTaskFomRecents(task);
                 return true;
             }
         }
@@ -125,25 +127,53 @@
             TaskStack stack = mTaskStackHorizontalView.getStack();
             Task task = stack.getLaunchTarget();
             if (task != null) {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+                launchTaskFomRecents(task);
                 return true;
             }
         }
         return false;
     }
 
-    /** Launches a given task. */
-    public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
-        if (mTaskStackHorizontalView != null) {
-            // Iterate the stack views and try and find the given task.
-            if (mTaskStackHorizontalView.getChildViewForTask(task) != null) {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
-                return true;
+    /**
+     * Launch the given task from recents with animation. If the task is not focused, this will
+     * attempt to scroll to focus the task before launching.
+     * @param task
+     */
+    private void launchTaskFomRecents(final Task task) {
+        if(task != mTaskStackHorizontalView.getFocusedTask()) {
+            if(mScrollListener != null) {
+                mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
             }
+            mScrollListener = new OnScrollListener() {
+                @Override
+                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+                    super.onScrollStateChanged(recyclerView, newState);
+                    if(newState == RecyclerView.SCROLL_STATE_IDLE) {
+                        TaskCardView cardView = mTaskStackHorizontalView.getChildViewForTask(task);
+                        if(cardView != null) {
+                            mTransitionHelper.launchTaskFromRecents(mStack, task,
+                                    mTaskStackHorizontalView, cardView, null, INVALID_STACK_ID);
+                        } else {
+                            // This should not happen normally. If this happens then the data in
+                            // the grid view was altered during the scroll. Log error and launch
+                            // task with no animation.
+                            Log.e(TAG, "Card view for task : " + task + ", returned null.");
+                            SystemServicesProxy ssp = Recents.getSystemServices();
+                            ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+                        }
+                        mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
+                    }
+                }
+            };
+            mTaskStackHorizontalView.addOnScrollListener(mScrollListener);
+            mTaskStackHorizontalView.setSelectedPositionSmooth(
+                    ((TaskStackHorizontalViewAdapter) mTaskStackHorizontalView.getAdapter())
+                            .getPositionOfTask(task));
+        } else {
+            mTransitionHelper.launchTaskFromRecents(mStack, task, mTaskStackHorizontalView,
+                    mTaskStackHorizontalView.getChildViewForTask(task), null,
+                    INVALID_STACK_ID);
         }
-        return false;
     }
 
     /**
@@ -218,9 +248,15 @@
         }
     }
 
-    public void setTaskStackViewAdapter(TaskStackHorizontalViewAdapter taskStackViewAdapter) {
+    public TaskStackHorizontalGridView setTaskStackViewAdapter(
+            TaskStackHorizontalViewAdapter taskStackViewAdapter) {
         if(mTaskStackHorizontalView != null) {
             mTaskStackHorizontalView.setAdapter(taskStackViewAdapter);
         }
+        return mTaskStackHorizontalView;
+    }
+
+    public TaskStackHorizontalGridView getGridView() {
+        return mTaskStackHorizontalView;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
index d605748..99d478b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
@@ -64,6 +64,7 @@
 
     @Override
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mThumbnailView = (ImageView) findViewById(R.id.card_view_thumbnail);
         mTitleTextView = (TextView) findViewById(R.id.card_title_text);
         mBadgeView = (ImageView) findViewById(R.id.card_extra_badge);
@@ -91,13 +92,6 @@
     public Rect getFocusedThumbnailRect() {
         Rect r = new Rect();
         mThumbnailView.getGlobalVisibleRect(r);
-        TypedValue out = new TypedValue();
-        getContext().getResources().getValue(R.integer.selected_scale, out, true);
-        float deltaScale = (out.getFloat() - 1.0f) / 2;
-        r.set((int) (r.left - r.left * deltaScale),
-                (int) (r.top - r.top * deltaScale),
-                (int) (r.right + r.right * deltaScale),
-                (int) (r.bottom + r.bottom * deltaScale));
         return r;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
index 3788719..97712ea 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
@@ -131,4 +131,9 @@
         mTaskList.remove(position);
         notifyItemRemoved(position);
     }
+
+    public int getPositionOfTask(Task task) {
+        int position = mTaskList.indexOf(task);
+        return (position >= 0) ? position : 0;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 9eec2ce..fd8df99 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -116,6 +116,7 @@
                     // window transition
                     EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
                     EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                    stackView.cancelAllTaskViewAnimations();
 
                     if (screenPinningRequested) {
                         // Request screen pinning after the animation runs
@@ -133,6 +134,7 @@
                     // window transition
                     EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
                     EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                    stackView.cancelAllTaskViewAnimations();
                 }
             };
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index f8ed700..6e585ae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -146,6 +146,8 @@
     AnimateableViewBounds mViewBounds;
 
     private AnimatorSet mTransformAnimation;
+    private ObjectAnimator mDimAnimator;
+    private ObjectAnimator mOutlineAnimator;
     private final TaskViewTransform mTargetAnimationTransform = new TaskViewTransform();
     private ArrayList<Animator> mTmpAnimators = new ArrayList<>();
 
@@ -308,14 +310,14 @@
         } else {
             // Both the progress and the update are a function of the bounds movement of the task
             if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
-                ObjectAnimator anim = ObjectAnimator.ofFloat(this, DIM_ALPHA, getDimAlpha(),
+                mDimAnimator = ObjectAnimator.ofFloat(this, DIM_ALPHA, getDimAlpha(),
                         toTransform.dimAlpha);
-                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
+                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mDimAnimator));
             }
             if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
-                ObjectAnimator anim = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
+                mOutlineAnimator = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
                         mViewBounds.getAlpha(), toTransform.viewOutlineAlpha);
-                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
+                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mOutlineAnimator));
             }
             if (updateCallback != null) {
                 ValueAnimator updateCallbackAnim = ValueAnimator.ofInt(0, 1);
@@ -358,6 +360,8 @@
      */
     public void cancelTransformAnimation() {
         Utilities.cancelAnimationWithoutCallbacks(mTransformAnimation);
+        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
+        Utilities.cancelAnimationWithoutCallbacks(mOutlineAnimator);
     }
 
     /** Enables/disables handling touch on this task view. */
@@ -537,13 +541,15 @@
     @Override
     public void onStartLaunchTargetEnterAnimation(TaskViewTransform transform, int duration,
             boolean screenPinningEnabled, ReferenceCountedTrigger postAnimationTrigger) {
+        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
+
         // Dim the view after the app window transitions down into recents
         postAnimationTrigger.increment();
         AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
-        Animator anim = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
+        mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
                 DIM_ALPHA_WITHOUT_HEADER, getDimAlpha(), transform.dimAlpha));
-        anim.addListener(postAnimationTrigger.decrementOnAnimationEnd());
-        anim.start();
+        mDimAnimator.addListener(postAnimationTrigger.decrementOnAnimationEnd());
+        mDimAnimator.start();
 
         if (screenPinningEnabled) {
             showActionButton(true /* fadeIn */, duration /* fadeInDuration */);
@@ -553,11 +559,13 @@
     @Override
     public void onStartLaunchTargetLaunchAnimation(int duration, boolean screenPinningRequested,
             ReferenceCountedTrigger postAnimationTrigger) {
+        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
+
         // Un-dim the view before/while launching the target
         AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
-        Animator anim = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
+        mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
                 DIM_ALPHA, getDimAlpha(), 0));
-        anim.start();
+        mDimAnimator.start();
 
         postAnimationTrigger.increment();
         hideActionButton(true /* fadeOut */, duration,
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index 9b56037..9294ecd 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -20,12 +20,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
-import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.widget.Toast;
 
+import com.android.systemui.R;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
-import com.android.systemui.recents.events.activity.ForcedResizableEvent;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 import com.android.systemui.stackdivider.events.StartedDragingEvent;
 import com.android.systemui.stackdivider.events.StoppedDragingEvent;
 
@@ -53,6 +55,18 @@
     public ForcedResizableInfoActivityController(Context context) {
         mContext = context;
         EventBus.getDefault().register(this);
+        SystemServicesProxy.getInstance(context).registerTaskStackListener(
+                new TaskStackListener() {
+                    @Override
+                    public void onActivityForcedResizable(String packageName, int taskId) {
+                        activityForcedResizable(packageName, taskId);
+                    }
+
+                    @Override
+                    public void onActivityDismissingDockedStack() {
+                        activityDismissingDockedStack();
+                    }
+                });
     }
 
     public void notifyDockedStackExistsChanged(boolean exists) {
@@ -61,14 +75,6 @@
         }
     }
 
-    public final void onBusEvent(ForcedResizableEvent forcedResizableEvent) {
-        if (debounce(forcedResizableEvent.packageName)) {
-            return;
-        }
-        mPendingTaskIds.add(forcedResizableEvent.taskId);
-        postTimeout();
-    }
-
     public final void onBusEvent(AppTransitionFinishedEvent event) {
         if (!mDividerDraging) {
             showPending();
@@ -85,6 +91,20 @@
         showPending();
     }
 
+    private void activityForcedResizable(String packageName, int taskId) {
+        if (debounce(packageName)) {
+            return;
+        }
+        mPendingTaskIds.add(taskId);
+        postTimeout();
+    }
+
+    private void activityDismissingDockedStack() {
+        Toast toast = Toast.makeText(mContext, R.string.dock_non_resizeble_failed_to_dock_text,
+                Toast.LENGTH_SHORT);
+        toast.show();
+    }
+
     private void showPending() {
         mHandler.removeCallbacks(mTimeoutRunnable);
         for (int i = mPendingTaskIds.size() - 1; i >= 0; i--) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 45e94f7..62c0fa9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -306,7 +306,7 @@
 
         // Calculate quick setting heights.
         int oldMaxHeight = mQsMaxExpansionHeight;
-        mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQsContainer.getHeader().getHeight();
+        mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQsContainer.getQsMinExpansionHeight();
         mQsMaxExpansionHeight = mQsContainer.getDesiredHeight();
         positionClockAndNotifications();
         if (mQsExpanded && mQsFullyExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index c9bb15d..c4b7932 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -845,15 +845,19 @@
     };
 
     public void cancelPeek() {
+        boolean cancelled = mPeekPending;
         if (mPeekAnimator != null) {
+            cancelled = true;
             mPeekAnimator.cancel();
         }
         removeCallbacks(mPeekRunnable);
         mPeekPending = false;
 
-        // When peeking, we already tell mBar that we expanded ourselves. Make sure that we also
-        // notify mBar that we might have closed ourselves.
-        notifyBarPanelExpansionChanged();
+        if (cancelled) {
+            // When peeking, we already tell mBar that we expanded ourselves. Make sure that we also
+            // notify mBar that we might have closed ourselves.
+            notifyBarPanelExpansionChanged();
+        }
     }
 
     public void expand(final boolean animate) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 902fd3d..cc3b4bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -41,7 +41,9 @@
     private Runnable mHideExpandedRunnable = new Runnable() {
         @Override
         public void run() {
-            mBar.makeExpandedInvisible();
+            if (mPanelFraction == 0.0f) {
+                mBar.makeExpandedInvisible();
+            }
         }
     };
 
@@ -135,6 +137,7 @@
         super.onTrackingStarted();
         mBar.onTrackingStarted();
         mScrimController.onTrackingStarted();
+        removePendingHideExpandedRunnables();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index e8170fb..ea9a5a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -45,7 +45,7 @@
 import com.android.systemui.tuner.TunerService;
 
 public class QuickStatusBarHeader extends BaseStatusBarHeader implements
-        NextAlarmChangeCallback, OnClickListener {
+        NextAlarmChangeCallback, OnClickListener, OnUserInfoChangedListener {
 
     private static final String TAG = "QuickStatusBarHeader";
 
@@ -54,7 +54,7 @@
     private ActivityStarter mActivityStarter;
     private NextAlarmController mNextAlarmController;
     private SettingsButton mSettingsButton;
-    private View mSettingsContainer;
+    protected View mSettingsContainer;
 
     private TextView mAlarmStatus;
     private TextView mAlarmStatusCollapsed;
@@ -75,19 +75,19 @@
 
     private QuickQSPanel mHeaderQsPanel;
     private boolean mShowEmergencyCallsOnly;
-    private MultiUserSwitch mMultiUserSwitch;
+    protected MultiUserSwitch mMultiUserSwitch;
     private ImageView mMultiUserAvatar;
 
     private float mDateTimeTranslation;
     private float mDateTimeAlarmTranslation;
     private float mDateScaleFactor;
-    private float mGearTranslation;
+    protected float mGearTranslation;
 
     private TouchAnimator mSecondHalfAnimator;
     private TouchAnimator mFirstHalfAnimator;
     private TouchAnimator mDateSizeAnimator;
     private TouchAnimator mAlarmTranslation;
-    private TouchAnimator mSettingsAlpha;
+    protected TouchAnimator mSettingsAlpha;
     private float mExpansionAmount;
     private QSTileHost mHost;
 
@@ -172,6 +172,11 @@
                 .addFloat(mDateTimeGroup, "scaleY", 1, mDateScaleFactor)
                 .setStartDelay(.36f)
                 .build();
+
+        updateSettingsAnimator();
+    }
+
+    protected void updateSettingsAnimator() {
         mSettingsAlpha = new TouchAnimator.Builder()
                 .addFloat(mSettingsContainer, "translationY", -mGearTranslation, 0)
                 .addFloat(mMultiUserSwitch, "translationY", -mGearTranslation, 0)
@@ -241,7 +246,7 @@
     @Override
     protected void onDetachedFromWindow() {
         setListening(false);
-        mHost.getUserInfoController().remListener(mUserListener);
+        mHost.getUserInfoController().remListener(this);
         mHost.getNetworkController().removeEmergencyListener(this);
         super.onDetachedFromWindow();
     }
@@ -275,7 +280,7 @@
         updateVisibilities();
     }
 
-    private void updateVisibilities() {
+    protected void updateVisibilities() {
         updateAlarmVisibilities();
         mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
                 ? View.VISIBLE : View.INVISIBLE);
@@ -365,7 +370,7 @@
 
     @Override
     public void setUserInfoController(UserInfoController userInfoController) {
-        userInfoController.addListener(mUserListener);
+        userInfoController.addListener(this);
     }
 
     @Override
@@ -379,10 +384,8 @@
         }
     }
 
-    private final OnUserInfoChangedListener mUserListener = new OnUserInfoChangedListener() {
-        @Override
-        public void onUserInfoChanged(String name, Drawable picture) {
-            mMultiUserAvatar.setImageDrawable(picture);
-        }
-    };
+    @Override
+    public void onUserInfoChanged(String name, Drawable picture) {
+        mMultiUserAvatar.setImageDrawable(picture);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index fa37e22..7c5cdfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -299,7 +299,7 @@
             setDimAmount((Float) animation.getAnimatedValue());
         }
     };
-    private ViewGroup mQsContainer;
+    protected ViewGroup mQsContainer;
     private boolean mContinuousShadowUpdate;
     private ViewTreeObserver.OnPreDrawListener mShadowUpdater
             = new ViewTreeObserver.OnPreDrawListener() {
@@ -3639,16 +3639,18 @@
             if (mTranslatingParentView == null) {
                 return false;
             }
-            final float snapBackThreshold = getSpaceForGear(animView);
+            // If the notification can't be dismissed then how far it can move is
+            // restricted -- reduce the distance it needs to move in this case.
+            final float multiplier = canChildBeDismissed(animView) ? 0.4f : 0.2f;
+            final float snapBackThreshold = getSpaceForGear(animView) * multiplier;
             final float translation = getTranslation(animView);
             final boolean fromLeft = translation > 0;
             final float absTrans = Math.abs(translation);
             final float notiThreshold = getSize(mTranslatingParentView) * 0.4f;
 
-            // If the notification can't be dismissed then how far it can move is
-            // restricted -- reduce the distance it needs to move in this case.
-            final float multiplier = canChildBeDismissed(animView) ? 0.4f : 0.2f;
-            return absTrans >= snapBackThreshold * 0.4f && absTrans <= notiThreshold;
+            return mCurrIconRow.isVisible() && (mCurrIconRow.isIconOnLeft()
+                    ? (translation > snapBackThreshold && translation <= notiThreshold)
+                    : (translation < -snapBackThreshold && translation >= -notiThreshold));
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index f9bb5e3..450001f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
@@ -29,12 +30,22 @@
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.tv.pip.PipManager;
 
-/*
+/**
  * Status bar implementation for "large screen" products that mostly present no on-screen nav
  */
 
 public class TvStatusBar extends BaseStatusBar {
 
+    /**
+     * Tracking calls to View.setSystemUiVisibility().
+     */
+    int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+
+    /**
+     * Last value sent to window manager.
+     */
+    private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
+
     @Override
     public void setIcon(String slot, StatusBarIcon icon) {
     }
@@ -207,4 +218,30 @@
     @Override
     public void clickTile(ComponentName tile) {
     }
+
+    @Override
+    public void start() {
+        super.start();
+        putComponent(TvStatusBar.class, this);
+    }
+
+    public void updateRecentsVisibility(boolean visible) {
+        // Update the recents visibility flag
+        if (visible) {
+            mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
+        } else {
+            mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
+        }
+        notifyUiVisibilityChanged(mSystemUiVisibility);
+    }
+
+    private void notifyUiVisibilityChanged(int vis) {
+        try {
+            if (mLastDispatchedSystemUiVisibility != vis) {
+                mWindowManagerService.statusBarVisibilityChanged(vis);
+                mLastDispatchedSystemUiVisibility = vis;
+            }
+        } catch (RemoteException ex) {
+        }
+    }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 3e7466f..613f890 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -363,12 +363,6 @@
     private void enableFeatures() {
         resetStreamState();
 
-        if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
-            mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper());
-            addFirstEventHandler(mMotionEventInjector);
-            mAms.setMotionEventInjector(mMotionEventInjector);
-        }
-
         if ((mEnabledFeatures & FLAG_FEATURE_AUTOCLICK) != 0) {
             mAutoclickController = new AutoclickController(mContext, mUserId);
             addFirstEventHandler(mAutoclickController);
@@ -384,6 +378,12 @@
             addFirstEventHandler(mMagnificationGestureHandler);
         }
 
+        if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
+            mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper());
+            addFirstEventHandler(mMotionEventInjector);
+            mAms.setMotionEventInjector(mMotionEventInjector);
+        }
+
         if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) {
             mKeyboardInterceptor = new KeyboardInterceptor(mAms);
             addFirstEventHandler(mKeyboardInterceptor);
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index b2196bf..fb1ef37 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -156,10 +156,10 @@
             final float offsetY = sentSpec.offsetY;
 
             // Compute the new center and update spec as needed.
-            final float centerX = (mMagnifiedBounds.width() / 2.0f
-                    + mMagnifiedBounds.left - offsetX) / scale;
-            final float centerY = (mMagnifiedBounds.height() / 2.0f
-                    + mMagnifiedBounds.top - offsetY) / scale;
+            final float centerX = (mMagnifiedBounds.width() / 2.0f - offsetX) / scale
+                    + mMagnifiedBounds.left;
+            final float centerY = (mMagnifiedBounds.height() / 2.0f - offsetY) / scale
+                    + mMagnifiedBounds.top;
             if (updateSpec) {
                 setScaleAndCenter(scale, centerX, centerY, false);
             } else {
@@ -256,7 +256,7 @@
     public float getCenterX() {
         synchronized (mLock) {
             return  (mMagnifiedBounds.width() / 2.0f
-                    + mMagnifiedBounds.left - getOffsetX()) / getScale();
+                   - getOffsetX()) / getScale() + mMagnifiedBounds.left;
         }
     }
 
@@ -279,7 +279,7 @@
     public float getCenterY() {
         synchronized (mLock) {
             return (mMagnifiedBounds.height() / 2.0f
-                    + mMagnifiedBounds.top - getOffsetY()) / getScale();
+                    - getOffsetY()) / getScale() + mMagnifiedBounds.top;
         }
     }
 
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 48e96aa..8753992 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -124,6 +124,7 @@
     private boolean mLastBatteryLevelCritical;
     private int mLastMaxChargingCurrent;
     private int mLastMaxChargingVoltage;
+    private int mLastChargeCounter;
 
     private int mInvalidCharger;
     private int mLastInvalidCharger;
@@ -341,6 +342,7 @@
                     + ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
                     + ", maxChargingCurrent" + mBatteryProps.maxChargingCurrent
                     + ", maxChargingVoltage" + mBatteryProps.maxChargingVoltage
+                    + ", chargeCounter" + mBatteryProps.batteryChargeCounter
                     + ", batteryStatus=" + mBatteryProps.batteryStatus
                     + ", batteryHealth=" + mBatteryProps.batteryHealth
                     + ", batteryPresent=" + mBatteryProps.batteryPresent
@@ -373,6 +375,7 @@
                 mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
                 mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent ||
                 mBatteryProps.maxChargingVoltage != mLastMaxChargingVoltage ||
+                mBatteryProps.batteryChargeCounter != mLastChargeCounter ||
                 mInvalidCharger != mLastInvalidCharger)) {
 
             if (mPlugType != mLastPlugType) {
@@ -501,6 +504,7 @@
             mLastBatteryTemperature = mBatteryProps.batteryTemperature;
             mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent;
             mLastMaxChargingVoltage = mBatteryProps.maxChargingVoltage;
+            mLastChargeCounter = mBatteryProps.batteryChargeCounter;
             mLastBatteryLevelCritical = mBatteryLevelCritical;
             mLastInvalidCharger = mInvalidCharger;
         }
@@ -527,6 +531,7 @@
         intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
         intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
         intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
+        intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
         if (DEBUG) {
             Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED.  level:" + mBatteryProps.batteryLevel +
                     ", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
@@ -540,7 +545,8 @@
                     ", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
                     ", icon:" + icon  + ", invalid charger:" + mInvalidCharger +
                     ", maxChargingCurrent:" + mBatteryProps.maxChargingCurrent +
-                    ", maxChargingVoltage:" + mBatteryProps.maxChargingVoltage);
+                    ", maxChargingVoltage:" + mBatteryProps.maxChargingVoltage +
+                    ", chargeCounter:" + mBatteryProps.batteryChargeCounter);
         }
 
         mHandler.post(new Runnable() {
@@ -772,6 +778,7 @@
                 pw.println("  Wireless powered: " + mBatteryProps.chargerWirelessOnline);
                 pw.println("  Max charging current: " + mBatteryProps.maxChargingCurrent);
                 pw.println("  Max charging voltage: " + mBatteryProps.maxChargingVoltage);
+                pw.println("  Charge counter: " + mBatteryProps.batteryChargeCounter);
                 pw.println("  status: " + mBatteryProps.batteryStatus);
                 pw.println("  health: " + mBatteryProps.batteryHealth);
                 pw.println("  present: " + mBatteryProps.batteryPresent);
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 440d8b7..fd9a94d 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -1984,6 +1984,28 @@
                 mHandler.obtainMessage(H_RESET).sendToTarget();
             }
         }
+
+        if ((mask & (StorageManager.DEBUG_SDCARDFS_FORCE_ON
+                | StorageManager.DEBUG_SDCARDFS_FORCE_OFF)) != 0) {
+            final String value;
+            if ((flags & StorageManager.DEBUG_SDCARDFS_FORCE_ON) != 0) {
+                value = "force_on";
+            } else if ((flags & StorageManager.DEBUG_SDCARDFS_FORCE_OFF) != 0) {
+                value = "force_off";
+            } else {
+                value = "";
+            }
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                SystemProperties.set(StorageManager.PROP_SDCARDFS, value);
+
+                // Reset storage to kick new setting into place
+                mHandler.obtainMessage(H_RESET).sendToTarget();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 8a0a62a..810270d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2884,7 +2884,6 @@
         }
         if (response == null) throw new IllegalArgumentException("response is null");
         if (account == null) throw new IllegalArgumentException("account is null");
-        if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4852788..0f48d21 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1467,6 +1467,7 @@
     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
+    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2056,6 +2057,21 @@
                 }
                 break;
             }
+                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
+                    synchronized (ActivityManagerService.this) {
+                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
+                            try {
+                                // Make a one-way callback to the listener
+                                mTaskStackListeners.getBroadcastItem(i)
+                                        .onActivityDismissingDockedStack();
+                            } catch (RemoteException e){
+                                // Handled by the RemoteCallbackList
+                            }
+                        }
+                        mTaskStackListeners.finishBroadcast();
+                    }
+                    break;
+                }
             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
                 final int uid = msg.arg1;
                 final byte[] firstPacket = (byte[]) msg.obj;
@@ -15641,8 +15657,8 @@
                     pw.println(totalPss - cachedPss);
                 }
             }
-            long lostRAM = memInfo.getTotalSizeKb()
-                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
+                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
             if (!isCompact) {
                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7b2a370..8395083 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -152,6 +152,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityManagerService.ANIMATE;
 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG;
 import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG;
 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
@@ -1810,7 +1811,7 @@
         if (DEBUG_STACK) Slog.d(TAG_STACK,
                 "findTaskToMoveToFront: moved to front of stack=" + task.stack);
 
-        showNonResizeableDockToastIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId);
+        handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId);
     }
 
     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
@@ -2392,7 +2393,7 @@
             resumeFocusedStackTopActivityLocked();
         }
 
-        showNonResizeableDockToastIfNeeded(task, preferredLaunchStackId, stackId);
+        handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId);
 
         return (preferredLaunchStackId == stackId);
     }
@@ -3363,15 +3364,19 @@
         }
     }
 
-    void showNonResizeableDockToastIfNeeded(
+    void handleNonResizableTaskIfNeeded(
             TaskRecord task, int preferredStackId, int actualStackId) {
-        if (!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID) {
+        if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
+                || task.isHomeTask()) {
             return;
         }
 
         if (!task.canGoInDockedStack()) {
             // Display a warning toast that we tried to put a non-dockable task in the docked stack.
-            mWindowManager.scheduleShowNonResizeableDockToast(task.taskId);
+            mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
+
+            // Dismiss docked stack.
+            mService.moveTasksToFullscreenStack(DOCKED_STACK_ID, false);
         } else if (task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) {
             String packageName = task.getTopActivity() != null
                     ? task.getTopActivity().appInfo.packageName : null;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 3bbc4521..771d5b2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -986,7 +986,7 @@
             }
             top.deliverNewIntentLocked(
                     mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
-            mSupervisor.showNonResizeableDockToastIfNeeded(mStartActivity.task,
+            mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.task,
                     preferredLaunchStackId, topStack.mStackId);
             return START_DELIVERED_TO_TOP;
         }
@@ -1074,7 +1074,7 @@
         }
         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
 
-        mSupervisor.showNonResizeableDockToastIfNeeded(
+        mSupervisor.handleNonResizableTaskIfNeeded(
                 mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId);
 
         return START_SUCCESS;
@@ -1382,6 +1382,9 @@
             mTargetStack.moveToFront("intentActivityFound");
         }
 
+        mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.task, INVALID_STACK_ID,
+                mTargetStack.mStackId);
+
         // If the caller has requested that the target task be reset, then do so.
         if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
             return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index e0a142b..bea26c7 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -237,10 +237,19 @@
                         AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
             }
 
-            // We only attempt to unlock real users here; we delay unlocking
-            // profiles until after the parent user is unlocked.
+            // We need to delay unlocking managed profiles until the parent user
+            // is also unlocked.
             if (getUserManager().isManagedProfile(userId)) {
-                Slog.d(TAG, "User " + userId + " is managed profile; delaying unlock attempt");
+                final UserInfo parent = getUserManager().getProfileParent(userId);
+                if (parent != null
+                        && isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
+                    Slog.d(TAG, "User " + userId + " (parent " + parent.id
+                            + "): attempting unlock because parent is unlocked");
+                    maybeUnlockUser(userId);
+                } else {
+                    Slog.d(TAG, "User " + userId + " (parent " + parent.id
+                            + "): delaying unlock because parent is locked");
+                }
             } else {
                 maybeUnlockUser(userId);
             }
@@ -909,17 +918,15 @@
         synchronized (mService) {
             final UserState uss = mStartedUsers.get(userId);
             finishUserUnlocking(uss, progress);
-        }
 
-        // We just unlocked a user, so let's now attempt to unlock any managed
-        // profiles under that user.
-        synchronized (mService) {
+            // We just unlocked a user, so let's now attempt to unlock any
+            // managed profiles under that user.
             for (int i = 0; i < mStartedUsers.size(); i++) {
                 final int testUserId = mStartedUsers.keyAt(i);
                 final UserInfo parent = getUserManager().getProfileParent(testUserId);
                 if (parent != null && parent.id == userId && testUserId != userId) {
-                    Slog.d(TAG, "Found user " + testUserId + " with parent " + userId
-                            + "; attempting unlock");
+                    Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
+                            + "): attempting unlock because parent was just unlocked");
                     maybeUnlockUser(testUserId);
                 }
             }
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index e08fad4..6b916be 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -39,7 +39,7 @@
 import android.location.IGnssStatusListener;
 import android.location.IGnssStatusProvider;
 import android.location.GnssMeasurementsEvent;
-import android.location.GnssNavigationMessageEvent;
+import android.location.GnssNavigationMessage;
 import android.location.IGpsGeofenceHardware;
 import android.location.ILocationManager;
 import android.location.INetInitiatedListener;
@@ -1662,7 +1662,7 @@
     /**
      * called from native code - GPS navigation message callback
      */
-    private void reportNavigationMessage(GnssNavigationMessageEvent event) {
+    private void reportNavigationMessage(GnssNavigationMessage event) {
         mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
     }
 
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index 734a8d4..caf1d6c 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -64,15 +64,15 @@
         int status;
         switch (result) {
             case RESULT_SUCCESS:
-                status = GnssMeasurementsEvent.STATUS_READY;
+                status = GnssMeasurementsEvent.Callback.STATUS_READY;
                 break;
             case RESULT_NOT_AVAILABLE:
             case RESULT_NOT_SUPPORTED:
             case RESULT_INTERNAL_ERROR:
-                status = GnssMeasurementsEvent.STATUS_NOT_SUPPORTED;
+                status = GnssMeasurementsEvent.Callback.STATUS_NOT_SUPPORTED;
                 break;
             case RESULT_GPS_LOCATION_DISABLED:
-                status = GnssMeasurementsEvent.STATUS_GNSS_LOCATION_DISABLED;
+                status = GnssMeasurementsEvent.Callback.STATUS_LOCATION_DISABLED;
                 break;
             case RESULT_UNKNOWN:
                 return null;
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index fdef31f..8d21928 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -16,7 +16,7 @@
 
 package com.android.server.location;
 
-import android.location.GnssNavigationMessageEvent;
+import android.location.GnssNavigationMessage;
 import android.location.IGnssNavigationMessageListener;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -37,7 +37,7 @@
         super(handler, TAG);
     }
 
-    public void onNavigationMessageAvailable(final GnssNavigationMessageEvent event) {
+    public void onNavigationMessageAvailable(final GnssNavigationMessage event) {
         ListenerOperation<IGnssNavigationMessageListener> operation =
                 new ListenerOperation<IGnssNavigationMessageListener>() {
                     @Override
@@ -65,16 +65,15 @@
         int status;
         switch (result) {
             case RESULT_SUCCESS:
-                status = GnssNavigationMessageEvent.STATUS_READY;
+                status = GnssNavigationMessage.Callback.STATUS_READY;
                 break;
             case RESULT_NOT_AVAILABLE:
             case RESULT_NOT_SUPPORTED:
             case RESULT_INTERNAL_ERROR:
-                status = GnssNavigationMessageEvent.STATUS_NOT_SUPPORTED;
+                status = GnssNavigationMessage.Callback.STATUS_NOT_SUPPORTED;
                 break;
             case RESULT_GPS_LOCATION_DISABLED:
-                status = GnssNavigationMessageEvent
-                        .STATUS_GNSS_LOCATION_DISABLED;
+                status = GnssNavigationMessage.Callback.STATUS_LOCATION_DISABLED;
                 break;
             case RESULT_UNKNOWN:
                 return null;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 928c19f..f6d2f7e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -862,8 +862,12 @@
                 IntentSender statusReceiver, int userId) {
         final int callingUid = Binder.getCallingUid();
         mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
+        boolean allowSilentUninstall = true;
         if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
             mAppOps.checkPackage(callingUid, callerPackageName);
+            final String installerPackageName = mPm.getInstallerPackageName(packageName);
+            allowSilentUninstall = installerPackageName != null
+                    && installerPackageName.equals(callerPackageName);
         }
 
         // Check whether the caller is device owner, in which case we do it silently.
@@ -874,8 +878,8 @@
 
         final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
                 statusReceiver, packageName, isDeviceOwner, userId);
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
-                == PackageManager.PERMISSION_GRANTED) {
+        if (allowSilentUninstall && mContext.checkCallingOrSelfPermission(
+                android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) {
             // Sweet, call straight through!
             mPm.deletePackage(packageName, adapter.getBinder(), userId, flags);
         } else if (isDeviceOwner) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a6fce51..7a61e79 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -76,7 +76,6 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
 import static android.content.pm.PackageParser.isApkFile;
-import static android.os.Process.FIRST_APPLICATION_UID;
 import static android.os.Process.PACKAGE_INFO_GID;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
@@ -117,7 +116,6 @@
 import android.content.IIntentReceiver;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.IntentFilter.AuthorityEntry;
 import android.content.IntentSender;
 import android.content.IntentSender.SendIntentException;
 import android.content.ServiceConnection;
@@ -150,7 +148,6 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.ActivityIntentInfo;
-import android.content.pm.PackageParser.IntentInfo;
 import android.content.pm.PackageParser.PackageLite;
 import android.content.pm.PackageParser.PackageParserException;
 import android.content.pm.PackageStats;
@@ -1066,8 +1063,9 @@
             | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
 
     final @Nullable String mRequiredVerifierPackage;
-    final @Nullable String mRequiredInstallerPackage;
+    final @NonNull String mRequiredInstallerPackage;
     final @Nullable String mSetupWizardPackage;
+    final @NonNull String mServicesSystemSharedLibraryPackageName;
 
     private final PackageUsage mPackageUsage = new PackageUsage();
 
@@ -2585,11 +2583,16 @@
                 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
                 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
                         mIntentFilterVerifierComponent);
+                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
+                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
+                getRequiredSharedLibraryLPr(
+                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
             } else {
                 mRequiredVerifierPackage = null;
                 mRequiredInstallerPackage = null;
                 mIntentFilterVerifierComponent = null;
                 mIntentFilterVerifier = null;
+                mServicesSystemSharedLibraryPackageName = null;
             }
 
             mInstallerService = new PackageInstallerService(context, this);
@@ -2669,6 +2672,16 @@
         }
     }
 
+    private @NonNull String getRequiredSharedLibraryLPr(String libraryName) {
+        synchronized (mPackages) {
+            SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName);
+            if (libraryEntry == null) {
+                throw new IllegalStateException("Missing required shared library:" + libraryName);
+            }
+            return libraryEntry.apk;
+        }
+    }
+
     private @NonNull String getRequiredInstallerLPr() {
         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
@@ -2678,6 +2691,10 @@
                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                 UserHandle.USER_SYSTEM);
         if (matches.size() == 1) {
+            ResolveInfo resolveInfo = matches.get(0);
+            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
+                throw new RuntimeException("The installer must be a privileged app");
+            }
             return matches.get(0).getComponentInfo().packageName;
         } else {
             throw new RuntimeException("There must be exactly one installer; found " + matches);
@@ -3560,15 +3577,10 @@
     }
 
     @Override
-    public @Nullable String getServicesSystemSharedLibraryPackageName() {
+    public @NonNull String getServicesSystemSharedLibraryPackageName() {
         synchronized (mPackages) {
-            SharedLibraryEntry libraryEntry = mSharedLibraries.get(
-                    PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
-            if (libraryEntry != null) {
-                return libraryEntry.apk;
-            }
+            return mServicesSystemSharedLibraryPackageName;
         }
-        return null;
     }
 
     @Override
@@ -11742,6 +11754,9 @@
 
             // Okay!
             targetPackageSetting.installerPackageName = installerPackageName;
+            if (installerPackageName != null) {
+                mSettings.mInstallerPackages.add(installerPackageName);
+            }
             scheduleWriteSettingsLocked();
         }
     }
@@ -14883,7 +14898,7 @@
      *  This method is an internal method that could be get invoked either
      *  to delete an installed package or to clean up a failed installation.
      *  After deleting an installed package, a broadcast is sent to notify any
-     *  listeners that the package has been installed. For cleaning up a failed
+     *  listeners that the package has been removed. For cleaning up a failed
      *  installation, the broadcast is not necessary since the package's
      *  installation wouldn't have sent the initial broadcast either
      *  The key steps in deleting a package are
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 3c3c576..24eac19 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -247,6 +247,9 @@
     /** Map from package name to settings */
     final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<>();
 
+    /** List of packages that installed other packages */
+    final ArraySet<String> mInstallerPackages = new ArraySet<>();
+
     /** Map from package name to appId */
     private final ArrayMap<String, Integer> mKernelMapping = new ArrayMap<>();
 
@@ -506,6 +509,9 @@
         PackageSetting p = mPackages.get(pkgName);
         if (p != null) {
             p.setInstallerPackageName(installerPkgName);
+            if (installerPkgName != null) {
+                mInstallerPackages.add(installerPkgName);
+            }
         }
     }
 
@@ -1062,6 +1068,7 @@
         final PackageSetting p = mPackages.get(name);
         if (p != null) {
             mPackages.remove(name);
+            removeInstallerPackageStatus(name);
             if (p.sharedUser != null) {
                 p.sharedUser.removePackage(p);
                 if (p.sharedUser.packages.size() == 0) {
@@ -1077,6 +1084,26 @@
         return -1;
     }
 
+    /**
+     * Checks if {@param packageName} is an installer package and if so, clear the installer
+     * package name of the packages that are installed by this.
+     */
+    private void removeInstallerPackageStatus(String packageName) {
+        // Check if the package to be removed is an installer package.
+        if (!mInstallerPackages.contains(packageName)) {
+            return;
+        }
+        for (int i = 0; i < mPackages.size(); i++) {
+            final PackageSetting ps = mPackages.valueAt(i);
+            final String installerPackageName = ps.getInstallerPackageName();
+            if (installerPackageName != null
+                    && installerPackageName.equals(packageName)) {
+                ps.setInstallerPackageName(null);
+            }
+        }
+        mInstallerPackages.remove(packageName);
+    }
+
     private void replacePackageLPw(String name, PackageSetting newp) {
         final PackageSetting p = mPackages.get(name);
         if (p != null) {
@@ -2742,6 +2769,7 @@
         mPendingPackages.clear();
         mPastSignatures.clear();
         mKeySetRefs.clear();
+        mInstallerPackages.clear();
 
         try {
             if (str == null) {
@@ -3706,6 +3734,10 @@
                 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
             }
 
+            if (installerPackageName != null) {
+                mInstallerPackages.add(installerPackageName);
+            }
+
             final String installStatusStr = parser.getAttributeValue(null, "installStatus");
             if (installStatusStr != null) {
                 if (installStatusStr.equalsIgnoreCase("false")) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 06a91fb..60a0d62 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -467,13 +467,16 @@
 
     @Override
     public List<UserInfo> getProfiles(int userId, boolean enabledOnly) {
+        boolean returnFullInfo = true;
         if (userId != UserHandle.getCallingUserId()) {
             checkManageUsersPermission("getting profiles related to user " + userId);
+        } else {
+            returnFullInfo = hasManageUsersPermission();
         }
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mUsersLock) {
-                return getProfilesLU(userId, enabledOnly);
+                return getProfilesLU(userId, enabledOnly, returnFullInfo);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -481,7 +484,7 @@
     }
 
     /** Assume permissions already checked and caller's identity cleared */
-    private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly) {
+    private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo) {
         UserInfo user = getUserInfoLU(userId);
         ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
         if (user == null) {
@@ -503,7 +506,14 @@
             if (profile.partial) {
                 continue;
             }
-            users.add(userWithName(profile));
+            UserInfo userInfo = userWithName(profile);
+            // If full info is not required - clear PII data to prevent 3P apps from reading it
+            if (!fullInfo) {
+                userInfo = new UserInfo(userInfo);
+                userInfo.name = null;
+                userInfo.iconPath = null;
+            }
+            users.add(userInfo);
         }
         return users;
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 8a9ace7..7b16dbe 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -16,24 +16,17 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.H.RESIZE_TASK;
-import static com.android.server.wm.WindowManagerService.H.SHOW_NON_RESIZEABLE_DOCK_TOAST;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
 
 import android.app.ActivityManager.StackId;
 import android.content.pm.ActivityInfo;
@@ -44,7 +37,6 @@
 import android.view.DisplayInfo;
 import android.view.Surface;
 
-import com.android.internal.R;
 import com.android.server.EventLogTags;
 
 import java.io.PrintWriter;
@@ -94,11 +86,6 @@
     // Resize mode of the task. See {@link ActivityInfo#resizeMode}
     private int mResizeMode;
 
-    // Whether we need to show toast about the app being non-resizeable when it becomes visible.
-    // This flag is set when a non-resizeable task is docked (or side-by-side). It's cleared
-    // after we show the toast.
-    private boolean mShowNonResizeableDockToast;
-
     // Whether the task is currently being drag-resized
     private boolean mDragResizing;
     private int mDragResizeMode;
@@ -118,30 +105,6 @@
         return mStack.getDisplayContent();
     }
 
-    void setShowNonResizeableDockToast() {
-        mShowNonResizeableDockToast = true;
-    }
-
-    void scheduleShowNonResizeableDockToastIfNeeded() {
-        if (!mShowNonResizeableDockToast) {
-            return;
-        }
-        final DisplayContent displayContent = mStack.getDisplayContent();
-        // If docked stack is not yet visible, we don't want to show the toast yet,
-        // since we need the visible rect of the docked task to position the toast.
-        if (displayContent == null || displayContent.getDockedStackLocked() == null) {
-            return;
-        }
-
-        mShowNonResizeableDockToast = false;
-
-        if (mResizeMode == RESIZE_MODE_UNRESIZEABLE) {
-            final String text =
-                    mService.mContext.getString(R.string.dock_non_resizeble_failed_to_dock_text);
-            mService.mH.obtainMessage(SHOW_NON_RESIZEABLE_DOCK_TOAST, 0, 0, text).sendToTarget();
-        }
-    }
-
     void addAppToken(int addPos, AppWindowToken wtoken, int resizeMode, boolean homeTask) {
         final int lastPos = mAppTokens.size();
         if (addPos >= lastPos) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2af324d..e32c976 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4940,17 +4940,6 @@
         }
     }
 
-    public void scheduleShowNonResizeableDockToast(int taskId) {
-        synchronized (mWindowMap) {
-            Task task = mTaskIdToTask.get(taskId);
-            if (task == null) {
-                if (DEBUG_STACK) Slog.i(TAG_WM, "scheduleShowToast: could not find taskId=" + taskId);
-                return;
-            }
-            task.setShowNonResizeableDockToast();
-        }
-    }
-
     @Override
     public void getStackBounds(int stackId, Rect bounds) {
         synchronized (mWindowMap) {
@@ -7770,7 +7759,6 @@
         public static final int RESIZE_TASK = 43;
 
         public static final int TWO_FINGER_SCROLL_START = 44;
-        public static final int SHOW_NON_RESIZEABLE_DOCK_TOAST = 45;
 
         public static final int WINDOW_REPLACEMENT_TIMEOUT = 46;
 
@@ -8338,16 +8326,6 @@
                     }
                 }
                 break;
-                case SHOW_NON_RESIZEABLE_DOCK_TOAST: {
-                    final Toast toast = Toast.makeText(
-                            mContext, (String) msg.obj, Toast.LENGTH_SHORT);
-                    final int gravity = toast.getGravity();
-                    final int xOffset = toast.getXOffset() + msg.arg1;
-                    final int yOffset = toast.getYOffset() + msg.arg2;
-                    toast.setGravity(gravity, xOffset, yOffset);
-                    toast.show();
-                }
-                break;
                 case WINDOW_REPLACEMENT_TIMEOUT: {
                     final AppWindowToken token = (AppWindowToken) msg.obj;
                     synchronized (mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ddfc022..de485de 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -734,8 +734,10 @@
             layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0;
             layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame;
             subtractInsets(mDisplayFrame, layoutContainingFrame, df);
-            subtractInsets(mContainingFrame, layoutContainingFrame, pf);
-            subtractInsets(mInsetFrame, layoutContainingFrame, pf);
+            if (!layoutInParentFrame()) {
+                subtractInsets(mContainingFrame, layoutContainingFrame, pf);
+                subtractInsets(mInsetFrame, layoutContainingFrame, pf);
+            }
             layoutDisplayFrame = df;
             layoutDisplayFrame.intersect(layoutContainingFrame);
         }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 34452ee..9e3a4db 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1483,11 +1483,6 @@
                 }
             }
             w.mToken.hasVisible = true;
-
-            final Task task = w.getTask();
-            if (task != null) {
-                task.scheduleShowNonResizeableDockToastIfNeeded();
-            }
         }
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 2399b3a..89272fa 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -639,7 +639,8 @@
         }
         // Add value to defaultPropsMap if needed
         if (typeArrayAndPropertiesPair.getSecond() != null) {
-            Object key = getCurrentParser().getViewCookie();
+            BridgeXmlBlockParser parser = getCurrentParser();
+            Object key = parser != null ? parser.getViewCookie() : null;
             if (key != null) {
                 PropertiesMap defaultPropMap = mDefaultPropMaps.get(key);
                 if (defaultPropMap == null) {
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 6ca4393..0f84506 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -152,6 +152,8 @@
     boolean enableAutoJoinWhenAssociated(boolean enabled);
     boolean getEnableAutoJoinWhenAssociated();
 
+    void enableWifiConnectivityManager(boolean enabled);
+
     WifiConnectionStatistics getConnectionStatistics();
 
     void disableEphemeralNetwork(String SSID);
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 6653a8d..6984fe2 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2719,4 +2719,16 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Enable/disable WifiConnectivityManager
+     * @hide
+     */
+    public void enableWifiConnectivityManager(boolean enabled) {
+        try {
+            mService.enableWifiConnectivityManager(enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 73ddbbc..f8c1ea3 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -810,19 +810,17 @@
     }
     /**
      * Stop an ongoing wifi PNO scan
-     * @param pnoSettings specifies various parameters for PNO; for more information look at
-     * {@link PnoSettings}
      * @param listener specifies which scan to cancel; must be same object as passed in {@link
      *  #startPnoScan}
      * TODO(rpius): Check if we can remove pnoSettings param in stop.
      * {@hide}
      */
-    public void stopPnoScan(PnoSettings pnoSettings, ScanListener listener) {
+    public void stopPnoScan(ScanListener listener) {
         Preconditions.checkNotNull(listener, "listener cannot be null");
         int key = removeListener(listener);
         if (key == INVALID_KEY) return;
         validateChannel();
-        sAsyncChannel.sendMessage(CMD_STOP_PNO_SCAN, 0, key, pnoSettings);
+        sAsyncChannel.sendMessage(CMD_STOP_PNO_SCAN, 0, key);
     }
 
     /** specifies information about an access point of interest */