Merge "Change the location of profile files." into nyc-dev
diff --git a/Android.mk b/Android.mk
index 6ec434c..b49d079 100644
--- a/Android.mk
+++ b/Android.mk
@@ -215,6 +215,7 @@
 	core/java/android/os/IBatteryPropertiesRegistrar.aidl \
 	core/java/android/os/ICancellationSignal.aidl \
 	core/java/android/os/IDeviceIdleController.aidl \
+	core/java/android/os/IHardwarePropertiesManager.aidl \
 	core/java/android/os/IMaintenanceActivityListener.aidl \
 	core/java/android/os/IMessenger.aidl \
 	core/java/android/os/INetworkActivityListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index 69eaa87..abc9e9a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4880,7 +4880,6 @@
     method public android.graphics.drawable.Icon getLargeIcon();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
-    method public android.app.Notification.Topic getTopic();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -4944,7 +4943,6 @@
     field public static final int PRIORITY_MAX = 2; // 0x2
     field public static final int PRIORITY_MIN = -2; // 0xfffffffe
     field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
-    field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
     field public static final int VISIBILITY_PRIVATE = 0; // 0x0
     field public static final int VISIBILITY_PUBLIC = 1; // 0x1
     field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5096,7 +5094,6 @@
     method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
     method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
     method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
-    method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
     method public android.app.Notification.Builder setUsesChronometer(boolean);
     method public android.app.Notification.Builder setVibrate(long[]);
     method public android.app.Notification.Builder setVisibility(int);
@@ -5134,6 +5131,16 @@
     method public android.app.PendingIntent getReplyPendingIntent();
   }
 
+  public static class Notification.DecoratedCustomViewStyle extends android.app.Notification.Style {
+    ctor public Notification.DecoratedCustomViewStyle();
+    ctor public Notification.DecoratedCustomViewStyle(android.app.Notification.Builder);
+  }
+
+  public static class Notification.DecoratedMediaCustomViewStyle extends android.app.Notification.MediaStyle {
+    ctor public Notification.DecoratedMediaCustomViewStyle();
+    ctor public Notification.DecoratedMediaCustomViewStyle(android.app.Notification.Builder);
+  }
+
   public static abstract interface Notification.Extender {
     method public abstract android.app.Notification.Builder extend(android.app.Notification.Builder);
   }
@@ -5164,16 +5171,6 @@
     field protected android.app.Notification.Builder mBuilder;
   }
 
-  public static class Notification.Topic implements android.os.Parcelable {
-    ctor public Notification.Topic(java.lang.String, java.lang.CharSequence);
-    method public android.app.Notification.Topic clone();
-    method public int describeContents();
-    method public java.lang.String getId();
-    method public java.lang.CharSequence getLabel();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.app.Notification.Topic> CREATOR;
-  }
-
   public static final class Notification.WearableExtender implements android.app.Notification.Extender {
     ctor public Notification.WearableExtender();
     ctor public Notification.WearableExtender(android.app.Notification);
@@ -5236,7 +5233,7 @@
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
-    method public int getImportance(java.lang.String);
+    method public int getImportance();
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
     method public void notify(int, android.app.Notification);
@@ -19167,9 +19164,9 @@
     method public double getDriftInNsPerSec();
     method public double getDriftUncertaintyInNsPerSec();
     method public long getFullBiasInNs();
+    method public int getHardwareClockDiscontinuityCount();
     method public short getLeapSecond();
     method public long getTimeInNs();
-    method public long getTimeOfLastHwClockDiscontinuityInNs();
     method public double getTimeUncertaintyInNs();
     method public byte getType();
     method public boolean hasBiasInNs();
@@ -19193,9 +19190,9 @@
     method public void setDriftInNsPerSec(double);
     method public void setDriftUncertaintyInNsPerSec(double);
     method public void setFullBiasInNs(long);
+    method public void setHardwareClockDiscontinuityCount(int);
     method public void setLeapSecond(short);
     method public void setTimeInNs(long);
-    method public void setTimeOfLastHwClockDiscontinuityInNs(long);
     method public void setTimeUncertaintyInNs(double);
     method public void setType(byte);
     method public void writeToParcel(android.os.Parcel, int);
@@ -19223,6 +19220,7 @@
     method public double getCn0InDbHz();
     method public double getCodePhaseInChips();
     method public double getCodePhaseUncertaintyInChips();
+    method public byte getConstellationType();
     method public double getDopplerShiftInHz();
     method public double getDopplerShiftUncertaintyInHz();
     method public double getElevationInDeg();
@@ -19230,13 +19228,11 @@
     method public byte getLossOfLock();
     method public byte getMultipathIndicator();
     method public double getPseudorangeInMeters();
-    method public double getPseudorangeRateCarrierInMetersPerSec();
-    method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec();
     method public double getPseudorangeRateInMetersPerSec();
     method public double getPseudorangeRateUncertaintyInMetersPerSec();
     method public double getPseudorangeUncertaintyInMeters();
-    method public long getReceivedGpsTowInNs();
-    method public long getReceivedGpsTowUncertaintyInNs();
+    method public long getReceivedSvTimeInNs();
+    method public long getReceivedSvTimeUncertaintyInNs();
     method public double getSnrInDb();
     method public short getState();
     method public short getSvid();
@@ -19293,6 +19289,7 @@
     method public void setCn0InDbHz(double);
     method public void setCodePhaseInChips(double);
     method public void setCodePhaseUncertaintyInChips(double);
+    method public void setConstellationType(byte);
     method public void setDopplerShiftInHz(double);
     method public void setDopplerShiftUncertaintyInHz(double);
     method public void setElevationInDeg(double);
@@ -19300,13 +19297,11 @@
     method public void setLossOfLock(byte);
     method public void setMultipathIndicator(byte);
     method public void setPseudorangeInMeters(double);
-    method public void setPseudorangeRateCarrierInMetersPerSec(double);
-    method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double);
     method public void setPseudorangeRateInMetersPerSec(double);
     method public void setPseudorangeRateUncertaintyInMetersPerSec(double);
     method public void setPseudorangeUncertaintyInMeters(double);
-    method public void setReceivedGpsTowInNs(long);
-    method public void setReceivedGpsTowUncertaintyInNs(long);
+    method public void setReceivedSvTimeInNs(long);
+    method public void setReceivedSvTimeUncertaintyInNs(long);
     method public void setSnrInDb(double);
     method public void setState(short);
     method public void setSvid(short);
@@ -19367,7 +19362,7 @@
     method public short getStatus();
     method public short getSubmessageId();
     method public short getSvid();
-    method public byte getType();
+    method public short getType();
     method public void reset();
     method public void set(android.location.GnssNavigationMessage);
     method public void setData(byte[]);
@@ -19375,14 +19370,19 @@
     method public void setStatus(short);
     method public void setSubmessageId(short);
     method public void setSvid(short);
-    method public void setType(byte);
+    method public void setType(short);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
-    field public static final byte MESSAGE_TYPE_CNAV2 = 4; // 0x4
-    field public static final byte MESSAGE_TYPE_L1CA = 1; // 0x1
-    field public static final byte MESSAGE_TYPE_L2CNAV = 2; // 0x2
-    field public static final byte MESSAGE_TYPE_L5CNAV = 3; // 0x3
-    field public static final byte MESSAGE_TYPE_UNKNOWN = 0; // 0x0
+    field public static final short MESSAGE_TYPE_BDS_D1 = 1281; // 0x501
+    field public static final short MESSAGE_TYPE_BDS_D2 = 1282; // 0x502
+    field public static final short MESSAGE_TYPE_GAL_F = 1538; // 0x602
+    field public static final short MESSAGE_TYPE_GAL_I = 1537; // 0x601
+    field public static final short MESSAGE_TYPE_GLO_L1CA = 769; // 0x301
+    field public static final short MESSAGE_TYPE_GPS_CNAV2 = 260; // 0x104
+    field public static final short MESSAGE_TYPE_GPS_L1CA = 257; // 0x101
+    field public static final short MESSAGE_TYPE_GPS_L2CNAV = 258; // 0x102
+    field public static final short MESSAGE_TYPE_GPS_L5CNAV = 259; // 0x103
+    field public static final short MESSAGE_TYPE_UNKNOWN = 0; // 0x0
     field public static final short STATUS_PARITY_PASSED = 1; // 0x1
     field public static final short STATUS_PARITY_REBUILT = 2; // 0x2
     field public static final short STATUS_UNKNOWN = 0; // 0x0
@@ -19417,7 +19417,7 @@
 
   public final class GnssStatus {
     method public float getAzimuth(int);
-    method public int getConstellationType(int);
+    method public byte getConstellationType(int);
     method public float getElevation(int);
     method public int getNumSatellites();
     method public float getSnr(int);
@@ -19425,13 +19425,16 @@
     method public boolean hasAlmanac(int);
     method public boolean hasEphemeris(int);
     method public boolean usedInFix(int);
-    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
-    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
-    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
-    field public static final int CONSTELLATION_GPS = 1; // 0x1
-    field public static final int CONSTELLATION_QZSS = 4; // 0x4
-    field public static final int CONSTELLATION_SBAS = 2; // 0x2
-    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
+    field public static final byte CONSTELLATION_BEIDOU = 5; // 0x5
+    field public static final byte CONSTELLATION_GALILEO = 6; // 0x6
+    field public static final byte CONSTELLATION_GLONASS = 3; // 0x3
+    field public static final byte CONSTELLATION_GPS = 1; // 0x1
+    field public static final byte CONSTELLATION_QZSS = 4; // 0x4
+    field public static final byte CONSTELLATION_SBAS = 2; // 0x2
+    field public static final byte CONSTELLATION_UNKNOWN = 0; // 0x0
+  }
+
+  public static abstract class GnssStatus.ConstellationType implements java.lang.annotation.Annotation {
   }
 
   public abstract class GnssStatusCallback {
@@ -20975,6 +20978,7 @@
     field public static final java.lang.String KEY_MAX_WIDTH = "max-width";
     field public static final java.lang.String KEY_MIME = "mime";
     field public static final java.lang.String KEY_OPERATING_RATE = "operating-rate";
+    field public static final java.lang.String KEY_PCM_ENCODING = "pcm-encoding";
     field public static final java.lang.String KEY_PRIORITY = "priority";
     field public static final java.lang.String KEY_PROFILE = "profile";
     field public static final java.lang.String KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
@@ -22549,6 +22553,10 @@
     method public void playFromMediaId(java.lang.String, android.os.Bundle);
     method public void playFromSearch(java.lang.String, android.os.Bundle);
     method public void playFromUri(android.net.Uri, android.os.Bundle);
+    method public void prepare();
+    method public void prepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void prepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void prepareFromUri(android.net.Uri, android.os.Bundle);
     method public void rewind();
     method public void seekTo(long);
     method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
@@ -22582,7 +22590,6 @@
     method public void setRatingType(int);
     method public void setSessionActivity(android.app.PendingIntent);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
-    field public static final int FLAG_HANDLES_PREPARE_ONLY = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
@@ -22597,6 +22604,10 @@
     method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
     method public void onPlayFromUri(android.net.Uri, android.os.Bundle);
+    method public void onPrepare();
+    method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
@@ -22653,6 +22664,10 @@
     field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
     field public static final long ACTION_PLAY_FROM_URI = 8192L; // 0x2000L
     field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
+    field public static final long ACTION_PREPARE = 16384L; // 0x4000L
+    field public static final long ACTION_PREPARE_FROM_MEDIA_ID = 32768L; // 0x8000L
+    field public static final long ACTION_PREPARE_FROM_SEARCH = 65536L; // 0x10000L
+    field public static final long ACTION_PREPARE_FROM_URI = 131072L; // 0x20000L
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
@@ -22661,7 +22676,6 @@
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
     field public static final long ACTION_STOP = 1L; // 0x1L
     field public static final android.os.Parcelable.Creator<android.media.session.PlaybackState> CREATOR;
-    field public static final java.lang.String EXTRA_PREPARE_ONLY = "android.media.session.extra.PREPARE_ONLY";
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
     field public static final int STATE_BUFFERING = 6; // 0x6
     field public static final int STATE_CONNECTING = 8; // 0x8
@@ -34591,6 +34605,7 @@
     method public final void startActivityAndCollapse(android.content.Intent);
     method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+    field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
     field public static final int TILE_MODE_ACTIVE = 2; // 0x2
     field public static final int TILE_MODE_PASSIVE = 1; // 0x1
   }
@@ -53058,7 +53073,7 @@
     ctor public ConnectionPendingException();
   }
 
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
diff --git a/api/system-current.txt b/api/system-current.txt
index 276fbd9..b36d7e8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5012,7 +5012,6 @@
     method public android.graphics.drawable.Icon getLargeIcon();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
-    method public android.app.Notification.Topic getTopic();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -5076,7 +5075,6 @@
     field public static final int PRIORITY_MAX = 2; // 0x2
     field public static final int PRIORITY_MIN = -2; // 0xfffffffe
     field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
-    field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
     field public static final int VISIBILITY_PRIVATE = 0; // 0x0
     field public static final int VISIBILITY_PUBLIC = 1; // 0x1
     field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5228,7 +5226,6 @@
     method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
     method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
     method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
-    method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
     method public android.app.Notification.Builder setUsesChronometer(boolean);
     method public android.app.Notification.Builder setVibrate(long[]);
     method public android.app.Notification.Builder setVisibility(int);
@@ -5266,6 +5263,16 @@
     method public android.app.PendingIntent getReplyPendingIntent();
   }
 
+  public static class Notification.DecoratedCustomViewStyle extends android.app.Notification.Style {
+    ctor public Notification.DecoratedCustomViewStyle();
+    ctor public Notification.DecoratedCustomViewStyle(android.app.Notification.Builder);
+  }
+
+  public static class Notification.DecoratedMediaCustomViewStyle extends android.app.Notification.MediaStyle {
+    ctor public Notification.DecoratedMediaCustomViewStyle();
+    ctor public Notification.DecoratedMediaCustomViewStyle(android.app.Notification.Builder);
+  }
+
   public static abstract interface Notification.Extender {
     method public abstract android.app.Notification.Builder extend(android.app.Notification.Builder);
   }
@@ -5296,16 +5303,6 @@
     field protected android.app.Notification.Builder mBuilder;
   }
 
-  public static class Notification.Topic implements android.os.Parcelable {
-    ctor public Notification.Topic(java.lang.String, java.lang.CharSequence);
-    method public android.app.Notification.Topic clone();
-    method public int describeContents();
-    method public java.lang.String getId();
-    method public java.lang.CharSequence getLabel();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.app.Notification.Topic> CREATOR;
-  }
-
   public static final class Notification.WearableExtender implements android.app.Notification.Extender {
     ctor public Notification.WearableExtender();
     ctor public Notification.WearableExtender(android.app.Notification);
@@ -5368,7 +5365,7 @@
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
-    method public int getImportance(java.lang.String);
+    method public int getImportance();
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
     method public void notify(int, android.app.Notification);
@@ -20348,9 +20345,9 @@
     method public double getDriftInNsPerSec();
     method public double getDriftUncertaintyInNsPerSec();
     method public long getFullBiasInNs();
+    method public int getHardwareClockDiscontinuityCount();
     method public short getLeapSecond();
     method public long getTimeInNs();
-    method public long getTimeOfLastHwClockDiscontinuityInNs();
     method public double getTimeUncertaintyInNs();
     method public byte getType();
     method public boolean hasBiasInNs();
@@ -20374,9 +20371,9 @@
     method public void setDriftInNsPerSec(double);
     method public void setDriftUncertaintyInNsPerSec(double);
     method public void setFullBiasInNs(long);
+    method public void setHardwareClockDiscontinuityCount(int);
     method public void setLeapSecond(short);
     method public void setTimeInNs(long);
-    method public void setTimeOfLastHwClockDiscontinuityInNs(long);
     method public void setTimeUncertaintyInNs(double);
     method public void setType(byte);
     method public void writeToParcel(android.os.Parcel, int);
@@ -20404,6 +20401,7 @@
     method public double getCn0InDbHz();
     method public double getCodePhaseInChips();
     method public double getCodePhaseUncertaintyInChips();
+    method public byte getConstellationType();
     method public double getDopplerShiftInHz();
     method public double getDopplerShiftUncertaintyInHz();
     method public double getElevationInDeg();
@@ -20411,13 +20409,11 @@
     method public byte getLossOfLock();
     method public byte getMultipathIndicator();
     method public double getPseudorangeInMeters();
-    method public double getPseudorangeRateCarrierInMetersPerSec();
-    method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec();
     method public double getPseudorangeRateInMetersPerSec();
     method public double getPseudorangeRateUncertaintyInMetersPerSec();
     method public double getPseudorangeUncertaintyInMeters();
-    method public long getReceivedGpsTowInNs();
-    method public long getReceivedGpsTowUncertaintyInNs();
+    method public long getReceivedSvTimeInNs();
+    method public long getReceivedSvTimeUncertaintyInNs();
     method public double getSnrInDb();
     method public short getState();
     method public short getSvid();
@@ -20474,6 +20470,7 @@
     method public void setCn0InDbHz(double);
     method public void setCodePhaseInChips(double);
     method public void setCodePhaseUncertaintyInChips(double);
+    method public void setConstellationType(byte);
     method public void setDopplerShiftInHz(double);
     method public void setDopplerShiftUncertaintyInHz(double);
     method public void setElevationInDeg(double);
@@ -20481,13 +20478,11 @@
     method public void setLossOfLock(byte);
     method public void setMultipathIndicator(byte);
     method public void setPseudorangeInMeters(double);
-    method public void setPseudorangeRateCarrierInMetersPerSec(double);
-    method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double);
     method public void setPseudorangeRateInMetersPerSec(double);
     method public void setPseudorangeRateUncertaintyInMetersPerSec(double);
     method public void setPseudorangeUncertaintyInMeters(double);
-    method public void setReceivedGpsTowInNs(long);
-    method public void setReceivedGpsTowUncertaintyInNs(long);
+    method public void setReceivedSvTimeInNs(long);
+    method public void setReceivedSvTimeUncertaintyInNs(long);
     method public void setSnrInDb(double);
     method public void setState(short);
     method public void setSvid(short);
@@ -20548,7 +20543,7 @@
     method public short getStatus();
     method public short getSubmessageId();
     method public short getSvid();
-    method public byte getType();
+    method public short getType();
     method public void reset();
     method public void set(android.location.GnssNavigationMessage);
     method public void setData(byte[]);
@@ -20556,14 +20551,19 @@
     method public void setStatus(short);
     method public void setSubmessageId(short);
     method public void setSvid(short);
-    method public void setType(byte);
+    method public void setType(short);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
-    field public static final byte MESSAGE_TYPE_CNAV2 = 4; // 0x4
-    field public static final byte MESSAGE_TYPE_L1CA = 1; // 0x1
-    field public static final byte MESSAGE_TYPE_L2CNAV = 2; // 0x2
-    field public static final byte MESSAGE_TYPE_L5CNAV = 3; // 0x3
-    field public static final byte MESSAGE_TYPE_UNKNOWN = 0; // 0x0
+    field public static final short MESSAGE_TYPE_BDS_D1 = 1281; // 0x501
+    field public static final short MESSAGE_TYPE_BDS_D2 = 1282; // 0x502
+    field public static final short MESSAGE_TYPE_GAL_F = 1538; // 0x602
+    field public static final short MESSAGE_TYPE_GAL_I = 1537; // 0x601
+    field public static final short MESSAGE_TYPE_GLO_L1CA = 769; // 0x301
+    field public static final short MESSAGE_TYPE_GPS_CNAV2 = 260; // 0x104
+    field public static final short MESSAGE_TYPE_GPS_L1CA = 257; // 0x101
+    field public static final short MESSAGE_TYPE_GPS_L2CNAV = 258; // 0x102
+    field public static final short MESSAGE_TYPE_GPS_L5CNAV = 259; // 0x103
+    field public static final short MESSAGE_TYPE_UNKNOWN = 0; // 0x0
     field public static final short STATUS_PARITY_PASSED = 1; // 0x1
     field public static final short STATUS_PARITY_REBUILT = 2; // 0x2
     field public static final short STATUS_UNKNOWN = 0; // 0x0
@@ -20598,7 +20598,7 @@
 
   public final class GnssStatus {
     method public float getAzimuth(int);
-    method public int getConstellationType(int);
+    method public byte getConstellationType(int);
     method public float getElevation(int);
     method public int getNumSatellites();
     method public float getSnr(int);
@@ -20606,13 +20606,16 @@
     method public boolean hasAlmanac(int);
     method public boolean hasEphemeris(int);
     method public boolean usedInFix(int);
-    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
-    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
-    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
-    field public static final int CONSTELLATION_GPS = 1; // 0x1
-    field public static final int CONSTELLATION_QZSS = 4; // 0x4
-    field public static final int CONSTELLATION_SBAS = 2; // 0x2
-    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
+    field public static final byte CONSTELLATION_BEIDOU = 5; // 0x5
+    field public static final byte CONSTELLATION_GALILEO = 6; // 0x6
+    field public static final byte CONSTELLATION_GLONASS = 3; // 0x3
+    field public static final byte CONSTELLATION_GPS = 1; // 0x1
+    field public static final byte CONSTELLATION_QZSS = 4; // 0x4
+    field public static final byte CONSTELLATION_SBAS = 2; // 0x2
+    field public static final byte CONSTELLATION_UNKNOWN = 0; // 0x0
+  }
+
+  public static abstract class GnssStatus.ConstellationType implements java.lang.annotation.Annotation {
   }
 
   public abstract class GnssStatusCallback {
@@ -22475,6 +22478,7 @@
     field public static final java.lang.String KEY_MAX_WIDTH = "max-width";
     field public static final java.lang.String KEY_MIME = "mime";
     field public static final java.lang.String KEY_OPERATING_RATE = "operating-rate";
+    field public static final java.lang.String KEY_PCM_ENCODING = "pcm-encoding";
     field public static final java.lang.String KEY_PRIORITY = "priority";
     field public static final java.lang.String KEY_PROFILE = "profile";
     field public static final java.lang.String KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
@@ -24122,6 +24126,10 @@
     method public void playFromMediaId(java.lang.String, android.os.Bundle);
     method public void playFromSearch(java.lang.String, android.os.Bundle);
     method public void playFromUri(android.net.Uri, android.os.Bundle);
+    method public void prepare();
+    method public void prepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void prepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void prepareFromUri(android.net.Uri, android.os.Bundle);
     method public void rewind();
     method public void seekTo(long);
     method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
@@ -24155,7 +24163,6 @@
     method public void setRatingType(int);
     method public void setSessionActivity(android.app.PendingIntent);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
-    field public static final int FLAG_HANDLES_PREPARE_ONLY = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
@@ -24170,6 +24177,10 @@
     method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
     method public void onPlayFromUri(android.net.Uri, android.os.Bundle);
+    method public void onPrepare();
+    method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
@@ -24226,6 +24237,10 @@
     field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
     field public static final long ACTION_PLAY_FROM_URI = 8192L; // 0x2000L
     field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
+    field public static final long ACTION_PREPARE = 16384L; // 0x4000L
+    field public static final long ACTION_PREPARE_FROM_MEDIA_ID = 32768L; // 0x8000L
+    field public static final long ACTION_PREPARE_FROM_SEARCH = 65536L; // 0x10000L
+    field public static final long ACTION_PREPARE_FROM_URI = 131072L; // 0x20000L
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
@@ -24234,7 +24249,6 @@
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
     field public static final long ACTION_STOP = 1L; // 0x1L
     field public static final android.os.Parcelable.Creator<android.media.session.PlaybackState> CREATOR;
-    field public static final java.lang.String EXTRA_PREPARE_ONLY = "android.media.session.extra.PREPARE_ONLY";
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
     field public static final int STATE_BUFFERING = 6; // 0x6
     field public static final int STATE_CONNECTING = 8; // 0x8
@@ -36983,9 +36997,8 @@
     field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb
     field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
     field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
-    field public static final int REASON_PACKAGE_SUSPENDED = 15; // 0xf
-    field public static final int REASON_PROFILE_TURNED_OFF = 16; // 0x10
-    field public static final int REASON_TOPIC_BANNED = 14; // 0xe
+    field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe
+    field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf
     field public static final int REASON_USER_STOPPED = 6; // 0x6
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
   }
@@ -37147,6 +37160,7 @@
     method public final void startActivityAndCollapse(android.content.Intent);
     method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+    field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
     field public static final int TILE_MODE_ACTIVE = 2; // 0x2
     field public static final int TILE_MODE_PASSIVE = 1; // 0x1
   }
@@ -48561,6 +48575,7 @@
     method public abstract void onConfigurationChanged(android.content.res.Configuration);
     method public abstract android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo);
     method public abstract void onDetachedFromWindow();
+    method public abstract boolean onDragEvent(android.view.DragEvent);
     method public abstract void onDraw(android.graphics.Canvas);
     method public abstract void onDrawVerticalScrollBar(android.graphics.Canvas, android.graphics.drawable.Drawable, int, int, int, int);
     method public abstract void onFinishTemporaryDetach();
@@ -56154,7 +56169,7 @@
     ctor public ConnectionPendingException();
   }
 
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 81c3f0b..3878fbf 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4880,7 +4880,6 @@
     method public android.graphics.drawable.Icon getLargeIcon();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
-    method public android.app.Notification.Topic getTopic();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -4944,7 +4943,6 @@
     field public static final int PRIORITY_MAX = 2; // 0x2
     field public static final int PRIORITY_MIN = -2; // 0xfffffffe
     field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
-    field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
     field public static final int VISIBILITY_PRIVATE = 0; // 0x0
     field public static final int VISIBILITY_PUBLIC = 1; // 0x1
     field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5096,7 +5094,6 @@
     method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
     method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
     method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
-    method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
     method public android.app.Notification.Builder setUsesChronometer(boolean);
     method public android.app.Notification.Builder setVibrate(long[]);
     method public android.app.Notification.Builder setVisibility(int);
@@ -5134,6 +5131,16 @@
     method public android.app.PendingIntent getReplyPendingIntent();
   }
 
+  public static class Notification.DecoratedCustomViewStyle extends android.app.Notification.Style {
+    ctor public Notification.DecoratedCustomViewStyle();
+    ctor public Notification.DecoratedCustomViewStyle(android.app.Notification.Builder);
+  }
+
+  public static class Notification.DecoratedMediaCustomViewStyle extends android.app.Notification.MediaStyle {
+    ctor public Notification.DecoratedMediaCustomViewStyle();
+    ctor public Notification.DecoratedMediaCustomViewStyle(android.app.Notification.Builder);
+  }
+
   public static abstract interface Notification.Extender {
     method public abstract android.app.Notification.Builder extend(android.app.Notification.Builder);
   }
@@ -5164,16 +5171,6 @@
     field protected android.app.Notification.Builder mBuilder;
   }
 
-  public static class Notification.Topic implements android.os.Parcelable {
-    ctor public Notification.Topic(java.lang.String, java.lang.CharSequence);
-    method public android.app.Notification.Topic clone();
-    method public int describeContents();
-    method public java.lang.String getId();
-    method public java.lang.CharSequence getLabel();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.app.Notification.Topic> CREATOR;
-  }
-
   public static final class Notification.WearableExtender implements android.app.Notification.Extender {
     ctor public Notification.WearableExtender();
     ctor public Notification.WearableExtender(android.app.Notification);
@@ -5236,7 +5233,7 @@
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
-    method public int getImportance(java.lang.String);
+    method public int getImportance();
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
     method public void notify(int, android.app.Notification);
@@ -19175,9 +19172,9 @@
     method public double getDriftInNsPerSec();
     method public double getDriftUncertaintyInNsPerSec();
     method public long getFullBiasInNs();
+    method public int getHardwareClockDiscontinuityCount();
     method public short getLeapSecond();
     method public long getTimeInNs();
-    method public long getTimeOfLastHwClockDiscontinuityInNs();
     method public double getTimeUncertaintyInNs();
     method public byte getType();
     method public boolean hasBiasInNs();
@@ -19201,9 +19198,9 @@
     method public void setDriftInNsPerSec(double);
     method public void setDriftUncertaintyInNsPerSec(double);
     method public void setFullBiasInNs(long);
+    method public void setHardwareClockDiscontinuityCount(int);
     method public void setLeapSecond(short);
     method public void setTimeInNs(long);
-    method public void setTimeOfLastHwClockDiscontinuityInNs(long);
     method public void setTimeUncertaintyInNs(double);
     method public void setType(byte);
     method public void writeToParcel(android.os.Parcel, int);
@@ -19231,6 +19228,7 @@
     method public double getCn0InDbHz();
     method public double getCodePhaseInChips();
     method public double getCodePhaseUncertaintyInChips();
+    method public byte getConstellationType();
     method public double getDopplerShiftInHz();
     method public double getDopplerShiftUncertaintyInHz();
     method public double getElevationInDeg();
@@ -19238,13 +19236,11 @@
     method public byte getLossOfLock();
     method public byte getMultipathIndicator();
     method public double getPseudorangeInMeters();
-    method public double getPseudorangeRateCarrierInMetersPerSec();
-    method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec();
     method public double getPseudorangeRateInMetersPerSec();
     method public double getPseudorangeRateUncertaintyInMetersPerSec();
     method public double getPseudorangeUncertaintyInMeters();
-    method public long getReceivedGpsTowInNs();
-    method public long getReceivedGpsTowUncertaintyInNs();
+    method public long getReceivedSvTimeInNs();
+    method public long getReceivedSvTimeUncertaintyInNs();
     method public double getSnrInDb();
     method public short getState();
     method public short getSvid();
@@ -19301,6 +19297,7 @@
     method public void setCn0InDbHz(double);
     method public void setCodePhaseInChips(double);
     method public void setCodePhaseUncertaintyInChips(double);
+    method public void setConstellationType(byte);
     method public void setDopplerShiftInHz(double);
     method public void setDopplerShiftUncertaintyInHz(double);
     method public void setElevationInDeg(double);
@@ -19308,13 +19305,11 @@
     method public void setLossOfLock(byte);
     method public void setMultipathIndicator(byte);
     method public void setPseudorangeInMeters(double);
-    method public void setPseudorangeRateCarrierInMetersPerSec(double);
-    method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double);
     method public void setPseudorangeRateInMetersPerSec(double);
     method public void setPseudorangeRateUncertaintyInMetersPerSec(double);
     method public void setPseudorangeUncertaintyInMeters(double);
-    method public void setReceivedGpsTowInNs(long);
-    method public void setReceivedGpsTowUncertaintyInNs(long);
+    method public void setReceivedSvTimeInNs(long);
+    method public void setReceivedSvTimeUncertaintyInNs(long);
     method public void setSnrInDb(double);
     method public void setState(short);
     method public void setSvid(short);
@@ -19375,7 +19370,7 @@
     method public short getStatus();
     method public short getSubmessageId();
     method public short getSvid();
-    method public byte getType();
+    method public short getType();
     method public void reset();
     method public void set(android.location.GnssNavigationMessage);
     method public void setData(byte[]);
@@ -19383,14 +19378,19 @@
     method public void setStatus(short);
     method public void setSubmessageId(short);
     method public void setSvid(short);
-    method public void setType(byte);
+    method public void setType(short);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
-    field public static final byte MESSAGE_TYPE_CNAV2 = 4; // 0x4
-    field public static final byte MESSAGE_TYPE_L1CA = 1; // 0x1
-    field public static final byte MESSAGE_TYPE_L2CNAV = 2; // 0x2
-    field public static final byte MESSAGE_TYPE_L5CNAV = 3; // 0x3
-    field public static final byte MESSAGE_TYPE_UNKNOWN = 0; // 0x0
+    field public static final short MESSAGE_TYPE_BDS_D1 = 1281; // 0x501
+    field public static final short MESSAGE_TYPE_BDS_D2 = 1282; // 0x502
+    field public static final short MESSAGE_TYPE_GAL_F = 1538; // 0x602
+    field public static final short MESSAGE_TYPE_GAL_I = 1537; // 0x601
+    field public static final short MESSAGE_TYPE_GLO_L1CA = 769; // 0x301
+    field public static final short MESSAGE_TYPE_GPS_CNAV2 = 260; // 0x104
+    field public static final short MESSAGE_TYPE_GPS_L1CA = 257; // 0x101
+    field public static final short MESSAGE_TYPE_GPS_L2CNAV = 258; // 0x102
+    field public static final short MESSAGE_TYPE_GPS_L5CNAV = 259; // 0x103
+    field public static final short MESSAGE_TYPE_UNKNOWN = 0; // 0x0
     field public static final short STATUS_PARITY_PASSED = 1; // 0x1
     field public static final short STATUS_PARITY_REBUILT = 2; // 0x2
     field public static final short STATUS_UNKNOWN = 0; // 0x0
@@ -19425,7 +19425,7 @@
 
   public final class GnssStatus {
     method public float getAzimuth(int);
-    method public int getConstellationType(int);
+    method public byte getConstellationType(int);
     method public float getElevation(int);
     method public int getNumSatellites();
     method public float getSnr(int);
@@ -19433,13 +19433,16 @@
     method public boolean hasAlmanac(int);
     method public boolean hasEphemeris(int);
     method public boolean usedInFix(int);
-    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
-    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
-    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
-    field public static final int CONSTELLATION_GPS = 1; // 0x1
-    field public static final int CONSTELLATION_QZSS = 4; // 0x4
-    field public static final int CONSTELLATION_SBAS = 2; // 0x2
-    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
+    field public static final byte CONSTELLATION_BEIDOU = 5; // 0x5
+    field public static final byte CONSTELLATION_GALILEO = 6; // 0x6
+    field public static final byte CONSTELLATION_GLONASS = 3; // 0x3
+    field public static final byte CONSTELLATION_GPS = 1; // 0x1
+    field public static final byte CONSTELLATION_QZSS = 4; // 0x4
+    field public static final byte CONSTELLATION_SBAS = 2; // 0x2
+    field public static final byte CONSTELLATION_UNKNOWN = 0; // 0x0
+  }
+
+  public static abstract class GnssStatus.ConstellationType implements java.lang.annotation.Annotation {
   }
 
   public abstract class GnssStatusCallback {
@@ -19545,8 +19548,8 @@
     method public void clearTestProviderStatus(java.lang.String);
     method public java.util.List<java.lang.String> getAllProviders();
     method public java.lang.String getBestProvider(android.location.Criteria, boolean);
+    method public int getGnssYearOfHardware();
     method public deprecated android.location.GpsStatus getGpsStatus(android.location.GpsStatus);
-    method public int getGpsYearOfHardware();
     method public android.location.Location getLastKnownLocation(java.lang.String);
     method public android.location.LocationProvider getProvider(java.lang.String);
     method public java.util.List<java.lang.String> getProviders(boolean);
@@ -20984,6 +20987,7 @@
     field public static final java.lang.String KEY_MAX_WIDTH = "max-width";
     field public static final java.lang.String KEY_MIME = "mime";
     field public static final java.lang.String KEY_OPERATING_RATE = "operating-rate";
+    field public static final java.lang.String KEY_PCM_ENCODING = "pcm-encoding";
     field public static final java.lang.String KEY_PRIORITY = "priority";
     field public static final java.lang.String KEY_PROFILE = "profile";
     field public static final java.lang.String KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
@@ -22558,6 +22562,10 @@
     method public void playFromMediaId(java.lang.String, android.os.Bundle);
     method public void playFromSearch(java.lang.String, android.os.Bundle);
     method public void playFromUri(android.net.Uri, android.os.Bundle);
+    method public void prepare();
+    method public void prepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void prepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void prepareFromUri(android.net.Uri, android.os.Bundle);
     method public void rewind();
     method public void seekTo(long);
     method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
@@ -22591,7 +22599,6 @@
     method public void setRatingType(int);
     method public void setSessionActivity(android.app.PendingIntent);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
-    field public static final int FLAG_HANDLES_PREPARE_ONLY = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
@@ -22606,6 +22613,10 @@
     method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
     method public void onPlayFromUri(android.net.Uri, android.os.Bundle);
+    method public void onPrepare();
+    method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
@@ -22662,6 +22673,10 @@
     field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
     field public static final long ACTION_PLAY_FROM_URI = 8192L; // 0x2000L
     field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
+    field public static final long ACTION_PREPARE = 16384L; // 0x4000L
+    field public static final long ACTION_PREPARE_FROM_MEDIA_ID = 32768L; // 0x8000L
+    field public static final long ACTION_PREPARE_FROM_SEARCH = 65536L; // 0x10000L
+    field public static final long ACTION_PREPARE_FROM_URI = 131072L; // 0x20000L
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
@@ -22670,7 +22685,6 @@
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
     field public static final long ACTION_STOP = 1L; // 0x1L
     field public static final android.os.Parcelable.Creator<android.media.session.PlaybackState> CREATOR;
-    field public static final java.lang.String EXTRA_PREPARE_ONLY = "android.media.session.extra.PREPARE_ONLY";
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
     field public static final int STATE_BUFFERING = 6; // 0x6
     field public static final int STATE_CONNECTING = 8; // 0x8
@@ -34606,6 +34620,7 @@
     method public final void startActivityAndCollapse(android.content.Intent);
     method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+    field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
     field public static final int TILE_MODE_ACTIVE = 2; // 0x2
     field public static final int TILE_MODE_PASSIVE = 1; // 0x1
   }
@@ -53075,7 +53090,7 @@
     ctor public ConnectionPendingException();
   }
 
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
diff --git a/cmds/hid/jni/Android.mk b/cmds/hid/jni/Android.mk
index 8163a9d..d41d39d 100644
--- a/cmds/hid/jni/Android.mk
+++ b/cmds/hid/jni/Android.mk
@@ -18,6 +18,6 @@
 LOCAL_MODULE := libhidcommand_jni
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_CFLAGS += -Wall
+LOCAL_CFLAGS += -Wall -Wextra -Werror
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 4278e7d..1ea33ce 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -49,7 +49,7 @@
     jmethodID onDeviceError;
 } gDeviceCallbackClassInfo;
 
-static int handleLooperEvents(int fd, int events, void* data) {
+static int handleLooperEvents(int /* fd */, int events, void* data) {
     Device* d = reinterpret_cast<Device*>(data);
     return d->handleEvents(events);
 }
@@ -183,7 +183,7 @@
     return data;
 }
 
-static jlong openDevice(JNIEnv* env, jclass clazz, jstring rawName, jint id, jint vid, jint pid,
+static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid, jint pid,
         jbyteArray rawDescriptor, jobject queue, jobject callback) {
     ScopedUtfChars name(env, rawName);
     if (name.c_str() == nullptr) {
@@ -202,7 +202,7 @@
     return reinterpret_cast<jlong>(d);
 }
 
-static void sendReport(JNIEnv* env, jclass clazz, jlong ptr,jbyteArray rawReport) {
+static void sendReport(JNIEnv* env, jclass /* clazz */, jlong ptr,jbyteArray rawReport) {
     size_t size;
     std::unique_ptr<uint8_t[]> report = getData(env, rawReport, size);
     uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
@@ -211,7 +211,7 @@
     }
 }
 
-static void closeDevice(JNIEnv* env, jclass clazz, jlong ptr) {
+static void closeDevice(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
     uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
     if (d) {
         delete d;
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 980329f..3385a17 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -807,6 +807,8 @@
     }
 
     /**
+     * AnimatorSet is only reversible when the set contains no sequential animation, and no child
+     * animators have a start delay.
      * @hide
      */
     @Override
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 04979ef..bb36a3e 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1532,6 +1532,14 @@
             return true;
         }
 
+        case SET_LENIENT_BACKGROUND_CHECK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            boolean enabled = data.readInt() != 0;
+            setLenientBackgroundCheck(enabled);
+            reply.writeNoException();
+            return true;
+        }
+
         case ENTER_SAFE_MODE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             enterSafeMode();
@@ -4855,6 +4863,17 @@
         data.recycle();
         reply.recycle();
     }
+    public void setLenientBackgroundCheck(boolean enabled) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(enabled ? 1 : 0);
+        mRemote.transact(SET_LENIENT_BACKGROUND_CHECK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
     public void enterSafeMode() throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index f0453e9..93452fd 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1265,6 +1265,14 @@
     }
 
     /** @hide */
+    public void setUserRestriction(int code, boolean restricted, IBinder token) {
+        try {
+            mService.setUserRestriction(code, restricted, token, mContext.getUserId());
+        } catch (RemoteException e) {
+        }
+    }
+
+    /** @hide */
     public void setMode(int code, int uid, String packageName, int mode) {
         try {
             mService.setMode(code, uid, packageName, mode);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index ca86c18..e4d6835 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -307,6 +307,7 @@
     public void setAlwaysFinish(boolean enabled) throws RemoteException;
     public void setActivityController(IActivityController watcher)
         throws RemoteException;
+    public void setLenientBackgroundCheck(boolean enabled) throws RemoteException;
 
     public void enterSafeMode() throws RemoteException;
 
@@ -978,4 +979,5 @@
     int SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 365;
     int NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 366;
     int REMOVE_STACK = IBinder.FIRST_CALL_TRANSACTION + 367;
+    int SET_LENIENT_BACKGROUND_CHECK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+368;
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 3c8dfce..8be00aa 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -48,16 +48,13 @@
     boolean areNotificationsEnabledForPackage(String pkg, int uid);
     boolean areNotificationsEnabled(String pkg);
 
-    ParceledListSlice getTopics(String pkg, int uid);
-    void setVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
-    int getVisibilityOverride(String pkg, int uid, in Notification.Topic topic);
-    void setPriority(String pkg, int uid, in Notification.Topic topic, int priority);
-    int getPriority(String pkg, int uid, in Notification.Topic topic);
-    void setImportance(String pkg, int uid, in Notification.Topic topic, int importance);
-    int getImportance(String pkg, int uid, in Notification.Topic topic);
-    int getTopicImportance(String pkg, String topicId);
-    boolean doesUserUseTopics(String pkg, int uid);
-    boolean hasBannedTopics(String pkg, int uid);
+    void setVisibilityOverride(String pkg, int uid, int visibility);
+    int getVisibilityOverride(String pkg, int uid);
+    void setPriority(String pkg, int uid, int priority);
+    int getPriority(String pkg, int uid);
+    void setImportance(String pkg, int uid, int importance);
+    int getImportance(String pkg, int uid);
+    int getPackageImportance(String pkg);
 
     // TODO: Remove this when callers have been migrated to the equivalent
     // INotificationListener method.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 52631d1..402c112 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -895,6 +895,11 @@
      */
     public static final String EXTRA_BUILDER_APPLICATION_INFO = "android.appInfo";
 
+    /**
+     * @hide
+     */
+    public static final String EXTRA_CONTAINS_CUSTOM_VIEW = "android.contains.customView";
+
     private Icon mSmallIcon;
     private Icon mLargeIcon;
 
@@ -1366,98 +1371,6 @@
     public Notification publicVersion;
 
     /**
-     * Structure to encapsulate a topic that is shown in Notification settings.
-     * It must include an id and label.
-     */
-    public static class Topic implements Parcelable {
-        private final String id;
-        private final CharSequence label;
-
-        public Topic(String id, CharSequence label) {
-            this.id = id;
-            this.label = safeCharSequence(label);
-        }
-
-        private Topic(Parcel in) {
-            if (in.readInt() != 0) {
-                id = in.readString();
-            } else {
-                id = null;
-            }
-            label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
-        }
-
-        public String getId() {
-            return id;
-        }
-
-        public CharSequence getLabel() {
-            return label;
-        }
-
-        @Override
-        public String toString() {
-            return new StringBuilder(Topic.class.getSimpleName()).append('[')
-                    .append("id=").append(id)
-                    .append(",label=").append(label)
-                    .append(']').toString();
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof Topic)) return false;
-            if (o == this) return true;
-            final Topic other = (Topic) o;
-            return Objects.equals(other.id, id)
-                    && Objects.equals(other.label, label);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(id, label);
-        }
-
-        @Override
-        public Topic clone() {
-            return new Topic(id, label);
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            if (id != null) {
-                out.writeInt(1);
-                out.writeString(id);
-            } else {
-                out.writeInt(0);
-            }
-            TextUtils.writeToParcel(label, out, flags);
-        }
-        public static final Parcelable.Creator<Topic> CREATOR =
-                new Parcelable.Creator<Topic>() {
-                    public Topic createFromParcel(Parcel in) {
-                        return new Topic(in);
-                    }
-                    public Topic[] newArray(int size) {
-                        return new Topic[size];
-                    }
-                };
-    }
-
-    @SystemApi
-    public static final String TOPIC_DEFAULT = "system_default_topic";
-
-    private Topic topic;
-
-    public Topic getTopic() {
-        return topic;
-    }
-
-    /**
      * Constructs a Notification object with default values.
      * You might want to consider using {@link Builder} instead.
      */
@@ -1583,10 +1496,6 @@
         }
 
         color = parcel.readInt();
-
-        if (parcel.readInt() != 0) {
-            topic = Topic.CREATOR.createFromParcel(parcel);
-        }
     }
 
     @Override
@@ -1687,10 +1596,6 @@
 
         that.color = this.color;
 
-        if (this.topic != null) {
-            that.topic = this.topic.clone();
-        }
-
         if (!heavy) {
             that.lightenPayload(); // will clean out extras
         }
@@ -1871,13 +1776,6 @@
         }
 
         parcel.writeInt(color);
-
-        if (topic != null) {
-            parcel.writeInt(1);
-            topic.writeToParcel(parcel, 0);
-        } else {
-            parcel.writeInt(0);
-        }
     }
 
     /**
@@ -2020,10 +1918,6 @@
             sb.append(" publicVersion=");
             sb.append(publicVersion.toString());
         }
-        if (topic != null) {
-            sb.append("topic=");
-            sb.append(topic.toString());
-        }
         sb.append(")");
         return sb.toString();
     }
@@ -2995,19 +2889,6 @@
             return this;
         }
 
-        /**
-         * Sets the topic of this notification. Topics are typically displayed in Notification
-         * settings.
-         * <p>
-         * Every topic must have an id and a textual label.
-         *
-         * @param topic The topic to add.
-         */
-        public Builder setTopic(Topic topic) {
-            mN.topic = topic;
-            return this;
-        }
-
         private Drawable getProfileBadgeDrawable() {
             // Note: This assumes that the current user can read the profile badge of the
             // originating user.
@@ -3353,7 +3234,7 @@
          *   3. Standard template view
          */
         public RemoteViews makeContentView() {
-            if (mN.contentView != null) {
+            if (mN.contentView != null && (mStyle == null || !mStyle.displayCustomViewInline())) {
                 return mN.contentView;
             } else if (mStyle != null) {
                 final RemoteViews styleView = mStyle.makeContentView();
@@ -3369,7 +3250,8 @@
          */
         public RemoteViews makeBigContentView() {
             RemoteViews result = null;
-            if (mN.bigContentView != null) {
+            if (mN.bigContentView != null
+                    && (mStyle == null || !mStyle.displayCustomViewInline())) {
                 return mN.bigContentView;
             } else if (mStyle != null) {
                 result = mStyle.makeBigContentView();
@@ -3410,7 +3292,8 @@
          * Construct a RemoteViews for the final heads-up notification layout.
          */
         public RemoteViews makeHeadsUpContentView() {
-            if (mN.headsUpContentView != null) {
+            if (mN.headsUpContentView != null
+                    && (mStyle == null ||  !mStyle.displayCustomViewInline())) {
                 return mN.headsUpContentView;
             } else if (mStyle != null) {
                     final RemoteViews styleView = mStyle.makeHeadsUpContentView();
@@ -3547,6 +3430,10 @@
                 mN.extras.putStringArray(EXTRA_PEOPLE,
                         mPersonList.toArray(new String[mPersonList.size()]));
             }
+            if (mN.bigContentView != null || mN.contentView != null
+                    || mN.headsUpContentView != null) {
+                mN.extras.putBoolean(EXTRA_CONTAINS_CUSTOM_VIEW, true);
+            }
             return mN;
         }
 
@@ -3571,8 +3458,9 @@
         }
 
         private static Class<? extends Style> getNotificationStyleClass(String templateClass) {
-            Class<? extends Style>[] classes = new Class[]{
-                    BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class};
+            Class<? extends Style>[] classes = new Class[] {
+                    BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
+                    DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class };
             for (Class<? extends Style> innerClass : classes) {
                 if (templateClass.equals(innerClass.getName())) {
                     return innerClass;
@@ -3877,6 +3765,14 @@
         public boolean hasSummaryInHeader() {
             return true;
         }
+
+        /**
+         * @hide
+         * @return Whether custom content views are displayed inline in the style
+         */
+        public boolean displayCustomViewInline() {
+            return false;
+        }
     }
 
     /**
@@ -4250,6 +4146,7 @@
             final float density = mBuilder.mContext.getResources().getDisplayMetrics().density;
             int topPadding = (int) (5 * density);
             int bottomPadding = (int) (13 * density);
+            boolean first = true;
             while (i < mTexts.size() && i < rowIds.length) {
                 CharSequence str = mTexts.get(i);
                 if (str != null && !str.equals("")) {
@@ -4261,23 +4158,26 @@
                     }
                     contentView.setViewPadding(rowIds[i], 0, topPadding, 0,
                             i == rowIds.length - 1 || i == mTexts.size() - 1 ? bottomPadding : 0);
+                    handleInboxImageMargin(contentView, rowIds[i], first);
+                    first = false;
                 }
                 i++;
             }
 
-            handleInboxImageMargin(contentView, rowIds[0]);
 
             return contentView;
         }
 
-        private void handleInboxImageMargin(RemoteViews contentView, int id) {
-            final int max = mBuilder.mN.extras.getInt(EXTRA_PROGRESS_MAX, 0);
-            final boolean ind = mBuilder.mN.extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
-            boolean hasProgress = max != 0 || ind;
+        private void handleInboxImageMargin(RemoteViews contentView, int id, boolean first) {
             int endMargin = 0;
-            if (mTexts.size() > 0 && mBuilder.mN.mLargeIcon != null && !hasProgress) {
-                endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
-                        R.dimen.notification_content_picture_margin);
+            if (first) {
+                final int max = mBuilder.mN.extras.getInt(EXTRA_PROGRESS_MAX, 0);
+                final boolean ind = mBuilder.mN.extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
+                boolean hasProgress = max != 0 || ind;
+                if (mBuilder.mN.mLargeIcon != null && !hasProgress) {
+                    endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
+                            R.dimen.notification_content_picture_margin);
+                }
             }
             contentView.setViewLayoutMarginEnd(id, endMargin);
         }
@@ -4460,13 +4360,11 @@
             }
             handleImage(view);
             // handle the content margin
-            int endMargin;
+            int endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_content_margin_end);;
             if (mBuilder.mN.mLargeIcon != null) {
-                endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
-                        R.dimen.notification_content_picture_margin_media);
-            } else {
-                endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
-                        R.dimen.notification_content_margin_end);
+                endMargin += mBuilder.mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_content_picture_margin);
             }
             view.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin);
             return view;
@@ -4513,6 +4411,214 @@
         }
     }
 
+    /**
+     * Notification style for custom views that are decorated by the system
+     *
+     * <p>Instead of providing a notification that is completely custom, a developer can set this
+     * style and still obtain system decorations like the notification header with the expand
+     * affordance and actions.
+     *
+     * <p>Use {@link android.app.Notification.Builder#setCustomContentView(RemoteViews)},
+     * {@link android.app.Notification.Builder#setCustomBigContentView(RemoteViews)} and
+     * {@link android.app.Notification.Builder#setCustomHeadsUpContentView(RemoteViews)} to set the
+     * corresponding custom views to display.
+     *
+     * To use this style with your Notification, feed it to
+     * {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
+     * <pre class="prettyprint">
+     * Notification noti = new Notification.Builder()
+     *     .setSmallIcon(R.drawable.ic_stat_player)
+     *     .setLargeIcon(albumArtBitmap))
+     *     .setCustomContentView(contentView);
+     *     .setStyle(<b>new Notification.DecoratedCustomViewStyle()</b>)
+     *     .build();
+     * </pre>
+     */
+    public static class DecoratedCustomViewStyle extends Style {
+
+        public DecoratedCustomViewStyle() {
+        }
+
+        public DecoratedCustomViewStyle(Builder builder) {
+            setBuilder(builder);
+        }
+
+        /**
+         * @hide
+         */
+        public boolean displayCustomViewInline() {
+            return true;
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public RemoteViews makeContentView() {
+            return makeStandardTemplateWithCustomContent(mBuilder.mN.contentView);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public RemoteViews makeBigContentView() {
+            return makeDecoratedBigContentView();
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public RemoteViews makeHeadsUpContentView() {
+            return makeDecoratedHeadsUpContentView();
+        }
+
+        private RemoteViews makeDecoratedHeadsUpContentView() {
+            RemoteViews headsUpContentView = mBuilder.mN.headsUpContentView == null
+                    ? mBuilder.mN.contentView
+                    : mBuilder.mN.headsUpContentView;
+            if (mBuilder.mActions.size() == 0) {
+               return makeStandardTemplateWithCustomContent(headsUpContentView);
+            }
+            RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions(
+                        mBuilder.getBigBaseLayoutResource());
+            buildIntoRemoteViewContent(remoteViews, headsUpContentView);
+            return remoteViews;
+        }
+
+        private RemoteViews makeStandardTemplateWithCustomContent(RemoteViews customContent) {
+            RemoteViews remoteViews = mBuilder.applyStandardTemplate(
+                    mBuilder.getBaseLayoutResource());
+            buildIntoRemoteViewContent(remoteViews, customContent);
+            return remoteViews;
+        }
+
+        private RemoteViews makeDecoratedBigContentView() {
+            RemoteViews bigContentView = mBuilder.mN.bigContentView == null
+                    ? mBuilder.mN.contentView
+                    : mBuilder.mN.bigContentView;
+            if (mBuilder.mActions.size() == 0) {
+                return makeStandardTemplateWithCustomContent(bigContentView);
+            }
+            RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions(
+                    mBuilder.getBigBaseLayoutResource());
+            buildIntoRemoteViewContent(remoteViews, bigContentView);
+            return remoteViews;
+        }
+
+        private void buildIntoRemoteViewContent(RemoteViews remoteViews,
+                RemoteViews customContent) {
+            remoteViews.removeAllViews(R.id.notification_main_column);
+            remoteViews.addView(R.id.notification_main_column, customContent);
+            // also update the end margin if there is an image
+            int endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_content_margin_end);
+            if (mBuilder.mN.mLargeIcon != null) {
+                endMargin += mBuilder.mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_content_picture_margin);
+            }
+            remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin);
+        }
+    }
+
+    /**
+     * Notification style for media custom views that are decorated by the system
+     *
+     * <p>Instead of providing a media notification that is completely custom, a developer can set
+     * this style and still obtain system decorations like the notification header with the expand
+     * affordance and actions.
+     *
+     * <p>Use {@link android.app.Notification.Builder#setCustomContentView(RemoteViews)},
+     * {@link android.app.Notification.Builder#setCustomBigContentView(RemoteViews)} and
+     * {@link android.app.Notification.Builder#setCustomHeadsUpContentView(RemoteViews)} to set the
+     * corresponding custom views to display.
+     *
+     * To use this style with your Notification, feed it to
+     * {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
+     * <pre class="prettyprint">
+     * Notification noti = new Notification.Builder()
+     *     .setSmallIcon(R.drawable.ic_stat_player)
+     *     .setLargeIcon(albumArtBitmap))
+     *     .setCustomContentView(contentView);
+     *     .setStyle(<b>new Notification.DecoratedMediaCustomViewStyle()</b>
+     *          .setMediaSession(mySession))
+     *     .build();
+     * </pre>
+     *
+     * @see android.app.Notification.DecoratedCustomViewStyle
+     * @see android.app.Notification.MediaStyle
+     */
+    public static class DecoratedMediaCustomViewStyle extends MediaStyle {
+
+        public DecoratedMediaCustomViewStyle() {
+        }
+
+        public DecoratedMediaCustomViewStyle(Builder builder) {
+            setBuilder(builder);
+        }
+
+        /**
+         * @hide
+         */
+        public boolean displayCustomViewInline() {
+            return true;
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public RemoteViews makeContentView() {
+            RemoteViews remoteViews = super.makeContentView();
+            return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
+                    mBuilder.mN.contentView);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public RemoteViews makeBigContentView() {
+            RemoteViews customRemoteView = mBuilder.mN.bigContentView != null
+                    ? mBuilder.mN.bigContentView
+                    : mBuilder.mN.contentView;
+            return makeBigContentViewWithCustomContent(customRemoteView);
+        }
+
+        private RemoteViews makeBigContentViewWithCustomContent(RemoteViews customRemoteView) {
+            RemoteViews remoteViews = super.makeBigContentView();
+            if (remoteViews != null) {
+                return buildIntoRemoteView(remoteViews, R.id.notification_main_column,
+                        customRemoteView);
+            } else if (customRemoteView != mBuilder.mN.contentView){
+                remoteViews = super.makeContentView();
+                return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
+                        customRemoteView);
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public RemoteViews makeHeadsUpContentView() {
+            RemoteViews customRemoteView = mBuilder.mN.headsUpContentView != null
+                    ? mBuilder.mN.headsUpContentView
+                    : mBuilder.mN.contentView;
+            return makeBigContentViewWithCustomContent(customRemoteView);
+        }
+
+        private RemoteViews buildIntoRemoteView(RemoteViews remoteViews, int id,
+                RemoteViews customContent) {
+            remoteViews.removeAllViews(id);
+            remoteViews.addView(id, customContent);
+            return remoteViews;
+        }
+    }
+
     // When adding a new Style subclass here, don't forget to update
     // Builder.getNotificationStyleClass.
 
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index ff2cfd6..324a0ab 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -507,11 +507,10 @@
         return false;
     }
 
-    public int getImportance(String topicId) {
-        Preconditions.checkNotNull(topicId);
+    public int getImportance() {
         INotificationManager service = getService();
         try {
-            return service.getTopicImportance(mContext.getPackageName(), topicId);
+            return service.getPackageImportance(mContext.getPackageName());
         } catch (RemoteException e) {
         }
         return NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index c552cfc..c1180e2 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -87,20 +87,20 @@
         }
         new Thread("SharedPreferencesImpl-load") {
             public void run() {
-                synchronized (SharedPreferencesImpl.this) {
-                    loadFromDiskLocked();
-                }
+                loadFromDisk();
             }
         }.start();
     }
 
-    private void loadFromDiskLocked() {
-        if (mLoaded) {
-            return;
-        }
-        if (mBackupFile.exists()) {
-            mFile.delete();
-            mBackupFile.renameTo(mFile);
+    private void loadFromDisk() {
+        synchronized (SharedPreferencesImpl.this) {
+            if (mLoaded) {
+                return;
+            }
+            if (mBackupFile.exists()) {
+                mFile.delete();
+                mBackupFile.renameTo(mFile);
+            }
         }
 
         // Debugging
@@ -118,27 +118,27 @@
                     str = new BufferedInputStream(
                             new FileInputStream(mFile), 16*1024);
                     map = XmlUtils.readMapXml(str);
-                } catch (XmlPullParserException e) {
-                    Log.w(TAG, "getSharedPreferences", e);
-                } catch (FileNotFoundException e) {
-                    Log.w(TAG, "getSharedPreferences", e);
-                } catch (IOException e) {
+                } catch (XmlPullParserException | IOException e) {
                     Log.w(TAG, "getSharedPreferences", e);
                 } finally {
                     IoUtils.closeQuietly(str);
                 }
             }
         } catch (ErrnoException e) {
+            /* ignore */
         }
-        mLoaded = true;
-        if (map != null) {
-            mMap = map;
-            mStatTimestamp = stat.st_mtime;
-            mStatSize = stat.st_size;
-        } else {
-            mMap = new HashMap<String, Object>();
+
+        synchronized (SharedPreferencesImpl.this) {
+            mLoaded = true;
+            if (map != null) {
+                mMap = map;
+                mStatTimestamp = stat.st_mtime;
+                mStatSize = stat.st_size;
+            } else {
+                mMap = new HashMap<>();
+            }
+            notifyAll();
         }
-        notifyAll();
     }
 
     static File makeBackupFile(File prefsFile) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 5eed781..52fba3b 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -89,6 +89,7 @@
 import android.os.DropBoxManager;
 import android.os.HardwarePropertiesManager;
 import android.os.IBinder;
+import android.os.IHardwarePropertiesManager;
 import android.os.IPowerManager;
 import android.os.IUserManager;
 import android.os.PowerManager;
@@ -715,7 +716,14 @@
                 new CachedServiceFetcher<HardwarePropertiesManager>() {
             @Override
             public HardwarePropertiesManager createService(ContextImpl ctx) {
-                return new HardwarePropertiesManager();
+                    IBinder b = ServiceManager.getService(Context.HARDWARE_PROPERTIES_SERVICE);
+                    IHardwarePropertiesManager service =
+                            IHardwarePropertiesManager.Stub.asInterface(b);
+                    if (service == null) {
+                        Log.wtf(TAG, "Failed to get hardwareproperties service.");
+                        return null;
+                    }
+                    return new HardwarePropertiesManager(ctx, service);
             }});
 
         registerService(Context.SOUND_TRIGGER_SERVICE, SoundTriggerManager.class,
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 1875e61..c3512ec 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -282,6 +282,10 @@
         }
 
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) {
+            return peekWallpaperBitmap(context, returnDefault, context.getUserId());
+        }
+
+        public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault, int userId) {
             synchronized (this) {
                 if (mService != null) {
                     try {
@@ -300,7 +304,7 @@
                 }
                 mWallpaper = null;
                 try {
-                    mWallpaper = getCurrentWallpaperLocked(context);
+                    mWallpaper = getCurrentWallpaperLocked(userId);
                 } catch (OutOfMemoryError e) {
                     Log.w(TAG, "No memory load current wallpaper", e);
                 }
@@ -323,7 +327,7 @@
             }
         }
 
-        private Bitmap getCurrentWallpaperLocked(Context context) {
+        private Bitmap getCurrentWallpaperLocked(int userId) {
             if (mService == null) {
                 Log.w(TAG, "WallpaperService not running");
                 return null;
@@ -332,7 +336,7 @@
             try {
                 Bundle params = new Bundle();
                 ParcelFileDescriptor fd = mService.getWallpaper(this, FLAG_SET_SYSTEM,
-                        params, context.getUserId());
+                        params, userId);
                 if (fd != null) {
                     try {
                         BitmapFactory.Options options = new BitmapFactory.Options();
@@ -644,7 +648,16 @@
      * @hide
      */
     public Bitmap getBitmap() {
-        return sGlobals.peekWallpaperBitmap(mContext, true);
+        return getBitmapAsUser(mContext.getUserId());
+    }
+
+    /**
+     * Like {@link #getDrawable()} but returns a Bitmap for the provided user.
+     *
+     * @hide
+     */
+    public Bitmap getBitmapAsUser(int userId) {
+        return sGlobals.peekWallpaperBitmap(mContext, true, userId);
     }
 
     /**
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index aa697ea..13ba6cc 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -211,6 +211,9 @@
         public int dozeScreenBrightness;
         public int dozeScreenState;
 
+        // If true, use twilight to affect the brightness.
+        public boolean useTwilight;
+
         public DisplayPowerRequest() {
             policy = POLICY_BRIGHT;
             useProximitySensor = false;
@@ -242,6 +245,7 @@
             boostScreenBrightness = other.boostScreenBrightness;
             dozeScreenBrightness = other.dozeScreenBrightness;
             dozeScreenState = other.dozeScreenState;
+            useTwilight = other.useTwilight;
         }
 
         @Override
@@ -262,7 +266,8 @@
                     && lowPowerMode == other.lowPowerMode
                     && boostScreenBrightness == other.boostScreenBrightness
                     && dozeScreenBrightness == other.dozeScreenBrightness
-                    && dozeScreenState == other.dozeScreenState;
+                    && dozeScreenState == other.dozeScreenState
+                    && useTwilight == other.useTwilight;
         }
 
         @Override
@@ -282,7 +287,8 @@
                     + ", lowPowerMode=" + lowPowerMode
                     + ", boostScreenBrightness=" + boostScreenBrightness
                     + ", dozeScreenBrightness=" + dozeScreenBrightness
-                    + ", dozeScreenState=" + Display.stateToString(dozeScreenState);
+                    + ", dozeScreenState=" + Display.stateToString(dozeScreenState)
+                    + ", useTwilight=" + useTwilight;
         }
 
         public static String policyToString(int policy) {
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 4487cab..c6d919f 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -57,90 +57,6 @@
     public native static int resetConnections(String interfaceName, int mask);
 
     /**
-     * Start the DHCP client daemon, in order to have it request addresses
-     * for the named interface.  This returns {@code true} if the DHCPv4 daemon
-     * starts, {@code false} otherwise.  This call blocks until such time as a
-     * result is available or the default discovery timeout has been reached.
-     * Callers should check {@link #getDhcpResults} to determine whether DHCP
-     * succeeded or failed, and if it succeeded, to fetch the {@link DhcpResults}.
-     * @param interfaceName the name of the interface to configure
-     * @return {@code true} for success, {@code false} for failure
-     */
-    public native static boolean startDhcp(String interfaceName);
-
-    /**
-     * Initiate renewal on the DHCP client daemon for the named interface.  This
-     * returns {@code true} if the DHCPv4 daemon has been notified, {@code false}
-     * otherwise.  This call blocks until such time as a result is available or
-     * the default renew timeout has been reached.  Callers should check
-     * {@link #getDhcpResults} to determine whether DHCP succeeded or failed,
-     * and if it succeeded, to fetch the {@link DhcpResults}.
-     * @param interfaceName the name of the interface to configure
-     * @return {@code true} for success, {@code false} for failure
-     */
-    public native static boolean startDhcpRenew(String interfaceName);
-
-    /**
-     * Start the DHCP client daemon, in order to have it request addresses
-     * for the named interface, and then configure the interface with those
-     * addresses. This call blocks until it obtains a result (either success
-     * or failure) from the daemon.
-     * @param interfaceName the name of the interface to configure
-     * @param dhcpResults if the request succeeds, this object is filled in with
-     * the IP address information.
-     * @return {@code true} for success, {@code false} for failure
-     */
-    public static boolean runDhcp(String interfaceName, DhcpResults dhcpResults) {
-        return startDhcp(interfaceName) && getDhcpResults(interfaceName, dhcpResults);
-    }
-
-    /**
-     * Initiate renewal on the DHCP client daemon. This call blocks until it obtains
-     * a result (either success or failure) from the daemon.
-     * @param interfaceName the name of the interface to configure
-     * @param dhcpResults if the request succeeds, this object is filled in with
-     * the IP address information.
-     * @return {@code true} for success, {@code false} for failure
-     */
-    public static boolean runDhcpRenew(String interfaceName, DhcpResults dhcpResults) {
-        return startDhcpRenew(interfaceName) && getDhcpResults(interfaceName, dhcpResults);
-    }
-
-    /**
-     * Fetch results from the DHCP client daemon. This call returns {@code true} if
-     * if there are results available to be read, {@code false} otherwise.
-     * @param interfaceName the name of the interface to configure
-     * @param dhcpResults if the request succeeds, this object is filled in with
-     * the IP address information.
-     * @return {@code true} for success, {@code false} for failure
-     */
-    public native static boolean getDhcpResults(String interfaceName, DhcpResults dhcpResults);
-
-    /**
-     * Shut down the DHCP client daemon.
-     * @param interfaceName the name of the interface for which the daemon
-     * should be stopped
-     * @return {@code true} for success, {@code false} for failure
-     */
-    public native static boolean stopDhcp(String interfaceName);
-
-    /**
-     * Release the current DHCP lease.
-     * @param interfaceName the name of the interface for which the lease should
-     * be released
-     * @return {@code true} for success, {@code false} for failure
-     */
-    public native static boolean releaseDhcpLease(String interfaceName);
-
-    /**
-     * Return the last DHCP-related error message that was recorded.
-     * <p/>NOTE: This string is not localized, but currently it is only
-     * used in logging.
-     * @return the most recent error message, if any
-     */
-    public native static String getDhcpError();
-
-    /**
      * Attaches a socket filter that accepts DHCP packets to the given socket.
      */
     public native static void attachDhcpFilter(FileDescriptor fd) throws SocketException;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b33e807..a738b2e 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2827,7 +2827,7 @@
         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
         dumpLine(pw, 0 /* uid */, category, GLOBAL_WIFI_DATA, wifiOnTime / 1000,
-                wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0, 0);
+                wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */ 0, 0, 0);
 
         dumpControllerActivityLine(pw, 0 /* uid */, category, GLOBAL_WIFI_CONTROLLER_DATA,
                 getWifiControllerActivity(), which);
diff --git a/core/java/android/os/CpuUsageInfo.aidl b/core/java/android/os/CpuUsageInfo.aidl
new file mode 100644
index 0000000..f81aefe
--- /dev/null
+++ b/core/java/android/os/CpuUsageInfo.aidl
@@ -0,0 +1,18 @@
+/* Copyright 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.os;
+
+parcelable CpuUsageInfo;
diff --git a/core/java/android/os/HardwarePropertiesManager.java b/core/java/android/os/HardwarePropertiesManager.java
index bc317b6..c72a6481 100644
--- a/core/java/android/os/HardwarePropertiesManager.java
+++ b/core/java/android/os/HardwarePropertiesManager.java
@@ -17,10 +17,12 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.content.Context;
+import android.util.Log;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-
 /**
  * The HardwarePropertiesManager class provides a mechanism of accessing hardware state of a
  * device: CPU, GPU and battery temperatures, CPU usage per core, fan speed, etc.
@@ -29,11 +31,7 @@
 
     private static final String TAG = HardwarePropertiesManager.class.getSimpleName();
 
-    private static native void nativeInit();
-
-    private static native float[] nativeGetFanSpeeds();
-    private static native float[] nativeGetDeviceTemperatures(int type);
-    private static native CpuUsageInfo[] nativeGetCpuUsages();
+    private final IHardwarePropertiesManager mService;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
@@ -54,9 +52,13 @@
     /** Temperature of battery in Celsius. */
     public static final int DEVICE_TEMPERATURE_BATTERY = 2;
 
+    /** Calling app context. */
+    private final Context mContext;
+
     /** @hide */
-    public HardwarePropertiesManager() {
-        nativeInit();
+    public HardwarePropertiesManager(Context context, IHardwarePropertiesManager service) {
+        mContext = context;
+        mService = service;
     }
 
     /**
@@ -68,13 +70,19 @@
      *         Empty if platform doesn't provide the queried temperature.
      *
      * @throws IllegalArgumentException if an incorrect temperature type is queried.
+     * @throws SecurityException if a non profile or device owner tries to call this method.
     */
     public @NonNull float[] getDeviceTemperatures(@DeviceTemperatureType int type) {
         switch (type) {
         case DEVICE_TEMPERATURE_CPU:
         case DEVICE_TEMPERATURE_GPU:
         case DEVICE_TEMPERATURE_BATTERY:
-            return nativeGetDeviceTemperatures(type);
+            try {
+                return mService.getDeviceTemperatures(mContext.getOpPackageName(), type);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Could not get device temperatures", e);
+                return new float[0];
+            }
         default:
             throw new IllegalArgumentException();
         }
@@ -85,18 +93,32 @@
      *
      * @return an array of {@link android.os.CpuUsageInfo} for each core.
      *         Empty if CPU usage is not supported on this system.
+     *
+     * @throws SecurityException if a non profile or device owner tries to call this method.
      */
     public @NonNull CpuUsageInfo[] getCpuUsages() {
-        return nativeGetCpuUsages();
+        try {
+            return mService.getCpuUsages(mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            Log.w(TAG, "Could not get CPU usages", e);
+            return new CpuUsageInfo[0];
+        }
     }
 
     /**
      * Return an array of fan speeds in RPM.
      *
-     * @return an arrat of float fan speeds. Empty if there is no fans or fan speed
-     *         not supported on this system.
+     * @return an array of float fan speeds in RPM. Empty if there are no fans or fan speed is not
+     * supported on this system.
+     *
+     * @throws SecurityException if a non profile or device owner tries to call this method.
      */
     public @NonNull float[] getFanSpeeds() {
-        return nativeGetFanSpeeds();
+        try {
+            return mService.getFanSpeeds(mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            Log.w(TAG, "Could not get fan speeds", e);
+            return new float[0];
+        }
     }
 }
diff --git a/core/java/android/os/IHardwarePropertiesManager.aidl b/core/java/android/os/IHardwarePropertiesManager.aidl
new file mode 100644
index 0000000..bcf0dc8
--- /dev/null
+++ b/core/java/android/os/IHardwarePropertiesManager.aidl
@@ -0,0 +1,28 @@
+/*
+**
+** Copyright 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.os;
+
+import android.os.CpuUsageInfo;
+
+/** @hide */
+
+interface IHardwarePropertiesManager {
+    float[] getDeviceTemperatures(String callingPackage, int type);
+    CpuUsageInfo[] getCpuUsages(String callingPackage);
+    float[] getFanSpeeds(String callingPackage);
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ec81050..770cde7 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -114,6 +114,21 @@
             "android.settings.LOCATION_SOURCE_SETTINGS";
 
     /**
+     * Activity Action: Show settings to allow configuration of users.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_USER_SETTINGS =
+            "android.settings.USER_SETTINGS";
+
+    /**
      * Activity Action: Show settings to allow configuration of wireless controls
      * such as Wi-Fi, Bluetooth and Mobile networks.
      * <p>
@@ -5924,6 +5939,52 @@
                 "camera_double_tap_power_gesture_disabled";
 
         /**
+
+        /**
+         * Behavior of twilight on the device.
+         * One of {@link #TWILIGHT_MODE_LOCKED_OFF}, {@link #TWILIGHT_MODE_LOCKED_ON}
+         * or {@link #TWILIGHT_MODE_AUTO}.
+         * @hide
+         */
+        public static final String TWILIGHT_MODE = "twilight_mode";
+
+        /**
+         * Twilight mode always off.
+         * @hide
+         */
+        public static final int TWILIGHT_MODE_LOCKED_OFF = 0;
+
+        /**
+         * Twilight mode always on.
+         * @hide
+         */
+        public static final int TWILIGHT_MODE_LOCKED_ON = 1;
+
+        /**
+         * Twilight mode auto.
+         * @hide
+         */
+        public static final int TWILIGHT_MODE_AUTO = 2;
+
+        /**
+         * Twilight mode auto, temporarily overriden to on.
+         * @hide
+         */
+        public static final int TWILIGHT_MODE_AUTO_OVERRIDE_OFF = 3;
+
+        /**
+         * Twilight mode auto, temporarily overriden to off.
+         * @hide
+         */
+        public static final int TWILIGHT_MODE_AUTO_OVERRIDE_ON = 4;
+
+        /**
+         * Whether brightness should automatically adjust based on twilight state.
+         * @hide
+         */
+        public static final String BRIGHTNESS_USE_TWILIGHT = "brightness_use_twilight";
+
+        /**
          * This are the settings to be backed up.
          *
          * NOTE: Settings are backed up and restored in the order they appear
@@ -7783,13 +7844,20 @@
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
 
          /**
-         * If 1, the activity manager will aggressively finish activities and
+         * If not 0, the activity manager will aggressively finish activities and
          * processes as soon as they are no longer needed.  If 0, the normal
          * extended lifetime is used.
          */
         public static final String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
 
         /**
+         * @hide
+         * If not 0, the activity manager will implement a looser version of background
+         * check that is more compatible with existing apps.
+         */
+        public static final String LENIENT_BACKGROUND_CHECK = "lenient_background_check";
+
+        /**
          * Use Dock audio output for media:
          *      0 = disabled
          *      1 = enabled
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index fb58f4e..b5387f1 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -97,14 +97,11 @@
     /** Notification was canceled because it was an invisible member of a group. */
     public static final int REASON_GROUP_OPTIMIZATION = 13;
 
-    /** Notification was canceled by the user banning the topic. */
-    public static final int REASON_TOPIC_BANNED = 14;
-
     /** Notification was canceled by the device administrator suspending the package. */
-    public static final int REASON_PACKAGE_SUSPENDED = 15;
+    public static final int REASON_PACKAGE_SUSPENDED = 14;
 
     /** Notification was canceled by the owning managed profile being turned off. */
-    public static final int REASON_PROFILE_TURNED_OFF = 16;
+    public static final int REASON_PROFILE_TURNED_OFF = 15;
 
     public class Adjustment {
         int mImportance;
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 0cf1175..553d539 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -16,6 +16,8 @@
 package android.service.quicksettings;
 
 import android.Manifest;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.app.Dialog;
 import android.app.Service;
@@ -74,6 +76,14 @@
 public class TileService extends Service {
 
     /**
+     * An activity that provides a user interface for adjusting TileService preferences.
+     * Optional but recommended for apps that implement a TileService.
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String ACTION_QS_TILE_PREFERENCES
+            = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
+
+    /**
      * Action that identifies a Service as being a TileService.
      */
     public static final String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
diff --git a/core/java/android/text/style/ReplacementSpan.java b/core/java/android/text/style/ReplacementSpan.java
index 26c725f..07190b2 100644
--- a/core/java/android/text/style/ReplacementSpan.java
+++ b/core/java/android/text/style/ReplacementSpan.java
@@ -16,18 +16,49 @@
 
 package android.text.style;
 
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Paint;
 import android.graphics.Canvas;
 import android.text.TextPaint;
 
 public abstract class ReplacementSpan extends MetricAffectingSpan {
 
-    public abstract int getSize(Paint paint, CharSequence text,
-                         int start, int end,
-                         Paint.FontMetricsInt fm);
-    public abstract void draw(Canvas canvas, CharSequence text,
-                     int start, int end, float x,
-                     int top, int y, int bottom, Paint paint);
+    /**
+     * Returns the width of the span. Extending classes can set the height of the span by updating
+     * attributes of {@link android.graphics.Paint.FontMetricsInt}. If the span covers the whole
+     * text, and the height is not set,
+     * {@link #draw(Canvas, CharSequence, int, int, float, int, int, int, Paint)} will not be
+     * called for the span.
+     *
+     * @param paint Paint instance.
+     * @param text Current text.
+     * @param start Start character index for span.
+     * @param end End character index for span.
+     * @param fm Font metrics, can be null.
+     * @return Width of the span.
+     */
+    public abstract int getSize(@NonNull Paint paint, CharSequence text,
+                        @IntRange(from = 0) int start, @IntRange(from = 0) int end,
+                        @Nullable Paint.FontMetricsInt fm);
+
+    /**
+     * Draws the span into the canvas.
+     *
+     * @param canvas Canvas into which the span should be rendered.
+     * @param text Current text.
+     * @param start Start character index for span.
+     * @param end End character index for span.
+     * @param x Edge of the replacement closest to the leading margin.
+     * @param top Top of the line.
+     * @param y Baseline.
+     * @param bottom Bottom of the line.
+     * @param paint Paint instance.
+     */
+    public abstract void draw(@NonNull Canvas canvas, CharSequence text,
+                              @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x,
+                              int top, int y, int bottom, @NonNull Paint paint);
 
     /**
      * This method does nothing, since ReplacementSpans are measured
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 664c02a..c7b1d03 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -1053,6 +1053,7 @@
         private void prefetchPredecessorsOfVirtualNode(AccessibilityNodeInfo root,
                 View providerHost, AccessibilityNodeProvider provider,
                 List<AccessibilityNodeInfo> outInfos) {
+            final int initialResultSize = outInfos.size();
             long parentNodeId = root.getParentNodeId();
             int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
             while (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
@@ -1071,6 +1072,12 @@
                                 AccessibilityNodeProvider.HOST_VIEW_ID);
                     }
                     if (parent == null) {
+                        // Going up the parent relation we found a null predecessor,
+                        // so remove these disconnected nodes form the result.
+                        final int currentResultSize = outInfos.size();
+                        for (int i = currentResultSize - 1; i >= initialResultSize; i--) {
+                            outInfos.remove(i);
+                        }
                         // Couldn't obtain the parent, which means we have a
                         // disconnected sub-tree. Abort prefetch immediately.
                         return;
diff --git a/core/java/android/view/IDockedStackListener.aidl b/core/java/android/view/IDockedStackListener.aidl
index 77fa7e2..cbc8dbd 100644
--- a/core/java/android/view/IDockedStackListener.aidl
+++ b/core/java/android/view/IDockedStackListener.aidl
@@ -33,4 +33,13 @@
      * Called when the docked stack gets created or removed.
      */
     void onDockedStackExistsChanged(boolean exists);
+
+    /**
+     * Called when window manager decides to minimize the docked stack. The divider should make
+     * itself not interactable and shrink a bit in this state.
+     *
+     * @param minimized Whether the docked stack is currently minimized.
+     * @param animDuration The duration of the animation for changing the minimized state.
+     */
+    void onDockedStackMinimizedChanged(boolean minimized, long animDuration);
 }
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 7017ff5..a4cb703 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -775,6 +775,10 @@
         mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
     }
 
+    public boolean isAttached() {
+        return mOwningView != null && mOwningView.mAttachInfo != null;
+    }
+
     public void addAnimator(AnimatedVectorDrawable.VectorDrawableAnimator animatorSet) {
         if (mOwningView == null || mOwningView.mAttachInfo == null) {
             throw new IllegalStateException("Cannot start this animator on a detached view!");
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index ca41d78..c972476 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -380,7 +380,7 @@
     void destroy() {
         mInitialized = false;
         updateEnabledState(null);
-        nDestroy(mNativeProxy);
+        nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
     }
 
     /**
@@ -994,7 +994,7 @@
             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);
-    private static native void nDestroy(long nativeProxy);
+    private static native void nDestroy(long nativeProxy, long rootRenderNode);
     private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
 
     private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 609c471..a8b7a7b 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -631,7 +631,7 @@
 
     /**
      * Return the display width available after excluding any screen
-     * decorations that can never be removed.  That is, system bar or
+     * decorations that could never be removed in Honeycomb. That is, system bar or
      * button bar.
      */
     public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation,
@@ -639,7 +639,7 @@
 
     /**
      * Return the display height available after excluding any screen
-     * decorations that can never be removed.  That is, system bar or
+     * decorations that could never be removed in Honeycomb. That is, system bar or
      * button bar.
      */
     public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation,
@@ -1350,4 +1350,16 @@
      */
     public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
             Rect outInsets);
+
+    /**
+     * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system
+     * bar or button bar. See {@link #getNonDecorDisplayWidth}.
+     *
+     * @param displayRotation the current display rotation
+     * @param displayWidth the current display width
+     * @param displayHeight the current display height
+     * @param outInsets the insets to return
+     */
+    public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
+            Rect outInsets);
 }
diff --git a/core/java/android/view/animation/ClipRectTBAnimation.java b/core/java/android/view/animation/ClipRectTBAnimation.java
deleted file mode 100644
index 06f86ce..0000000
--- a/core/java/android/view/animation/ClipRectTBAnimation.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2015 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.view.animation;
-
-import android.graphics.Rect;
-
-/**
- * Special case of ClipRectAnimation that animates only the top/bottom
- * dimensions of the clip, picking up the other dimensions from whatever is
- * set on the transform already.
- *
- * @hide
- */
-public class ClipRectTBAnimation extends ClipRectAnimation {
-
-    /**
-     * Constructor. Passes in 0 for Left/Right parameters of ClipRectAnimation
-     */
-    public ClipRectTBAnimation(int fromT, int fromB, int toT, int toB) {
-        super(0, fromT, 0, fromB, 0, toT, 0, toB);
-    }
-
-    /**
-     * Calculates and sets clip rect on given transformation. It uses existing values
-     * on the Transformation for Left/Right clip parameters.
-     */
-    @Override
-    protected void applyTransformation(float it, Transformation tr) {
-        Rect oldClipRect = tr.getClipRect();
-        tr.setClipRect(oldClipRect.left, mFromRect.top + (int) ((mToRect.top - mFromRect.top) * it),
-                oldClipRect.right,
-                mFromRect.bottom + (int) ((mToRect.bottom - mFromRect.bottom) * it));
-    }
-
-}
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index d97f8af..281babe 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -428,18 +428,6 @@
         }
     }
 
-    /**
-     * @return {@code true} if the {@link android.inputmethodservice.InputMethodService} is marked
-     * to be Encryption-Aware.
-     * @hide
-     */
-    public boolean isEncryptionAware() {
-        if (mService == null || mService.serviceInfo == null) {
-            return false;
-        }
-        return mService.serviceInfo.encryptionAware;
-    }
-
     public void dump(Printer pw, String prefix) {
         pw.println(prefix + "mId=" + mId
                 + " mSettingsActivityName=" + mSettingsActivityName
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 0f58ba3..647d4dc 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -39,6 +39,7 @@
 import android.security.KeyChain;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.DragEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
@@ -2528,6 +2529,11 @@
     }
 
     @Override
+    public boolean onDragEvent(DragEvent event) {
+        return mProvider.getViewDelegate().onDragEvent(event);
+    }
+
+    @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
         // This method may be called in the constructor chain, before the WebView provider is
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 3ce034c..94d231c 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -30,6 +30,7 @@
 import android.os.Bundle;
 import android.os.Message;
 import android.print.PrintDocumentAdapter;
+import android.view.DragEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
@@ -334,6 +335,8 @@
 
         public InputConnection onCreateInputConnection(EditorInfo outAttrs);
 
+        public boolean onDragEvent(DragEvent event);
+
         public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event);
 
         public boolean onKeyDown(int keyCode, KeyEvent event);
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 9fa2c23..b13be97 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -44,6 +44,7 @@
     int checkAudioOperation(int code, int usage, int uid, String packageName);
     void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages);
 
-    void setUserRestrictions(in Bundle restrictions, int userHandle);
+    void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
+    void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle);
     void removeUser(int userHandle);
 }
diff --git a/core/java/com/android/internal/policy/DockedDividerUtils.java b/core/java/com/android/internal/policy/DockedDividerUtils.java
index 00c65bd..c68e506 100644
--- a/core/java/com/android/internal/policy/DockedDividerUtils.java
+++ b/core/java/com/android/internal/policy/DockedDividerUtils.java
@@ -17,9 +17,9 @@
 package com.android.internal.policy;
 
 import android.graphics.Rect;
-import android.view.WindowManager;
 
 import static android.view.WindowManager.DOCKED_BOTTOM;
+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;
@@ -35,46 +35,61 @@
             int displayWidth, int displayHeight, int dividerSize) {
         outRect.set(0, 0, displayWidth, displayHeight);
         switch (dockSide) {
-            case WindowManager.DOCKED_LEFT:
+            case DOCKED_LEFT:
                 outRect.right = position;
                 break;
-            case WindowManager.DOCKED_TOP:
+            case DOCKED_TOP:
                 outRect.bottom = position;
                 break;
-            case WindowManager.DOCKED_RIGHT:
+            case DOCKED_RIGHT:
                 outRect.left = position + dividerSize;
                 break;
-            case WindowManager.DOCKED_BOTTOM:
+            case DOCKED_BOTTOM:
                 outRect.top = position + dividerSize;
                 break;
         }
-        sanitizeStackBounds(outRect);
+        sanitizeStackBounds(outRect, dockSide == DOCKED_LEFT || dockSide == DOCKED_TOP);
     }
 
-    public static void sanitizeStackBounds(Rect bounds) {
-        if (bounds.left >= bounds.right) {
-            bounds.left = bounds.right - 1;
-        }
-        if (bounds.top >= bounds.bottom) {
-            bounds.top = bounds.bottom - 1;
-        }
-        if (bounds.right <= bounds.left) {
-            bounds.right = bounds.left + 1;
-        }
-        if (bounds.bottom <= bounds.top) {
-            bounds.bottom = bounds.top + 1;
+    /**
+     * Makes sure that the bounds are always valid, i. e. they are at least one pixel high and wide.
+     *
+     * @param bounds The bounds to sanitize.
+     * @param topLeft Pass true if the bounds are at the top/left of the screen, false if they are
+     *                at the bottom/right. This is used to determine in which direction to extend
+     *                the bounds.
+     */
+    public static void sanitizeStackBounds(Rect bounds, boolean topLeft) {
+
+        // If the bounds are either on the top or left of the screen, rather move it further to the
+        // left/top to make it more offscreen. If they are on the bottom or right, push them off the
+        // screen by moving it even more to the bottom/right.
+        if (topLeft) {
+            if (bounds.left >= bounds.right) {
+                bounds.left = bounds.right - 1;
+            }
+            if (bounds.top >= bounds.bottom) {
+                bounds.top = bounds.bottom - 1;
+            }
+        } else {
+            if (bounds.right <= bounds.left) {
+                bounds.right = bounds.left + 1;
+            }
+            if (bounds.bottom <= bounds.top) {
+                bounds.bottom = bounds.top + 1;
+            }
         }
     }
 
     public static int calculatePositionForBounds(Rect bounds, int dockSide, int dividerSize) {
         switch (dockSide) {
-            case WindowManager.DOCKED_LEFT:
+            case DOCKED_LEFT:
                 return bounds.right;
-            case WindowManager.DOCKED_TOP:
+            case DOCKED_TOP:
                 return bounds.bottom;
-            case WindowManager.DOCKED_RIGHT:
+            case DOCKED_RIGHT:
                 return bounds.left - dividerSize;
-            case WindowManager.DOCKED_BOTTOM:
+            case DOCKED_BOTTOM:
                 return bounds.top - dividerSize;
             default:
                 return 0;
@@ -109,16 +124,16 @@
 
     public static int invertDockSide(int dockSide) {
         switch (dockSide) {
-            case WindowManager.DOCKED_LEFT:
-                return WindowManager.DOCKED_RIGHT;
-            case WindowManager.DOCKED_TOP:
-                return WindowManager.DOCKED_BOTTOM;
-            case WindowManager.DOCKED_RIGHT:
-                return WindowManager.DOCKED_LEFT;
-            case WindowManager.DOCKED_BOTTOM:
-                return WindowManager.DOCKED_TOP;
+            case DOCKED_LEFT:
+                return DOCKED_RIGHT;
+            case DOCKED_TOP:
+                return DOCKED_BOTTOM;
+            case DOCKED_RIGHT:
+                return DOCKED_LEFT;
+            case DOCKED_BOTTOM:
+                return DOCKED_TOP;
             default:
-                return WindowManager.DOCKED_INVALID;
+                return DOCKED_INVALID;
         }
     }
 }
diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java
index b45fd06..6bba1b3 100644
--- a/core/java/com/android/internal/widget/MediaNotificationView.java
+++ b/core/java/com/android/internal/widget/MediaNotificationView.java
@@ -21,6 +21,7 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.RemoteViews;
@@ -31,16 +32,16 @@
  * @hide
  */
 @RemoteViews.RemoteView
-public class MediaNotificationView extends RelativeLayout {
+public class MediaNotificationView extends FrameLayout {
 
     private final int mMaxImageSize;
-    private final int mImageMarginBottom;
     private final int mImageMinTopMargin;
     private final int mNotificationContentMarginEnd;
     private final int mNotificationContentImageMarginEnd;
     private ImageView mRightIcon;
     private View mActions;
     private View mHeader;
+    private View mMainColumn;
 
     public MediaNotificationView(Context context) {
         this(context, null);
@@ -61,39 +62,49 @@
         if (hasIcon && mode != MeasureSpec.UNSPECIFIED) {
             measureChild(mActions, widthMeasureSpec, heightMeasureSpec);
             int size = MeasureSpec.getSize(widthMeasureSpec);
-            int height = MeasureSpec.getSize(heightMeasureSpec);
             size = size - mActions.getMeasuredWidth();
             ViewGroup.MarginLayoutParams layoutParams =
                     (MarginLayoutParams) mRightIcon.getLayoutParams();
-            size -= layoutParams.getMarginEnd();
+            int imageEndMargin = layoutParams.getMarginEnd();
+            size -= imageEndMargin;
             size = Math.min(size, mMaxImageSize);
             size = Math.max(size, mRightIcon.getMinimumWidth());
             layoutParams.width = size;
             layoutParams.height = size;
-            // because we can't allign it to the bottom with a margin, we add a topmargin to it
-            layoutParams.topMargin = height - size - mImageMarginBottom;
-            // If the topMargin is high enough we can also remove the header constraint!
-            if (layoutParams.topMargin >= mImageMinTopMargin) {
-                resetHeaderIndention();
-            } else {
-                int paddingEnd = mNotificationContentImageMarginEnd;
-                ViewGroup.MarginLayoutParams headerParams =
-                        (MarginLayoutParams) mHeader.getLayoutParams();
-                headerParams.setMarginEnd(size + layoutParams.getMarginEnd());
-                if (mHeader.getPaddingEnd() != paddingEnd) {
-                    mHeader.setPadding(
-                            isLayoutRtl() ? paddingEnd : mHeader.getPaddingLeft(),
-                            mHeader.getPaddingTop(),
-                            isLayoutRtl() ? mHeader.getPaddingLeft() : paddingEnd,
-                            mHeader.getPaddingBottom());
-                    mHeader.setLayoutParams(headerParams);
-                }
-            }
             mRightIcon.setLayoutParams(layoutParams);
-        } else if (!hasIcon && mHeader.getPaddingEnd() != mNotificationContentMarginEnd) {
-            resetHeaderIndention();
+
+            // lets ensure that the main column doesn't run into the image
+            ViewGroup.MarginLayoutParams mainParams
+                    = (MarginLayoutParams) mMainColumn.getLayoutParams();
+            int marginEnd = size + imageEndMargin + mNotificationContentMarginEnd;
+            if (marginEnd != mainParams.getMarginEnd()) {
+                mainParams.setMarginEnd(marginEnd);
+                mMainColumn.setLayoutParams(mainParams);
+            }
+
         }
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        ViewGroup.MarginLayoutParams iconParams =
+                (MarginLayoutParams) mRightIcon.getLayoutParams();
+        int topMargin = getMeasuredHeight() - mRightIcon.getMeasuredHeight()
+                - iconParams.bottomMargin;
+        // If the topMargin is high enough we can also remove the header constraint!
+        if (!hasIcon || topMargin >= mImageMinTopMargin) {
+            resetHeaderIndention();
+        } else {
+            int paddingEnd = mNotificationContentImageMarginEnd;
+            ViewGroup.MarginLayoutParams headerParams =
+                    (MarginLayoutParams) mHeader.getLayoutParams();
+            headerParams.setMarginEnd(mRightIcon.getMeasuredWidth() + iconParams.getMarginEnd());
+            if (mHeader.getPaddingEnd() != paddingEnd) {
+                mHeader.setPadding(
+                        isLayoutRtl() ? paddingEnd : mHeader.getPaddingLeft(),
+                        mHeader.getPaddingTop(),
+                        isLayoutRtl() ? mHeader.getPaddingLeft() : paddingEnd,
+                        mHeader.getPaddingBottom());
+                mHeader.setLayoutParams(headerParams);
+            }
+        }
     }
 
     private void resetHeaderIndention() {
@@ -115,8 +126,6 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         mMaxImageSize = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.media_notification_expanded_image_max_size);
-        mImageMarginBottom = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.media_notification_expanded_image_margin_bottom);
         mImageMinTopMargin = (int) (context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_top)
                 + getResources().getDisplayMetrics().density * 2);
@@ -132,5 +141,6 @@
         mRightIcon = (ImageView) findViewById(com.android.internal.R.id.right_icon);
         mActions = findViewById(com.android.internal.R.id.media_actions);
         mHeader = findViewById(com.android.internal.R.id.notification_header);
+        mMainColumn = findViewById(com.android.internal.R.id.notification_main_column);
     }
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 1b6b53a..8b686b7 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -177,8 +177,7 @@
     com_android_internal_net_NetworkStatsFactory.cpp \
     com_android_internal_os_Zygote.cpp \
     com_android_internal_util_VirtualRefBasePtr.cpp \
-    com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp \
-    android_os_HardwarePropertiesManager.cpp
+    com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
 
 LOCAL_C_INCLUDES += \
     $(JNI_H_INCLUDE) \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 223fc1a..017fb53 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -198,7 +198,6 @@
 extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
 extern int register_com_android_internal_os_Zygote(JNIEnv *env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
-extern int register_android_os_HardwarePropertiesManager(JNIEnv *env);
 
 static AndroidRuntime* gCurRuntime = NULL;
 
@@ -1390,7 +1389,6 @@
     REG_JNI(register_android_animation_PropertyValuesHolder),
     REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
     REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
-    REG_JNI(register_android_os_HardwarePropertiesManager),
 
 };
 
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
index ae99f0b..731d22a 100644
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
@@ -39,7 +39,6 @@
 #include <SkPoint.h>
 #include <SkRect.h>
 #include <SkTypeface.h>
-#include <SkUtils.h>
 
 #include <hb.h>
 
@@ -82,17 +81,16 @@
 static hb_bool_t harfbuzzGetGlyph(hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t variationSelector, hb_codepoint_t* glyph, void* userData)
 {
     HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
+    SkPaint* paint = hbFontData->m_paint;
+    paint->setTextEncoding(SkPaint::kUTF32_TextEncoding);
 
     if (unicode > 0x10ffff) {
         unicode = 0xfffd;
     }
-    SkPaint* paint = hbFontData->m_paint;
-    // It would be better to use kUTF32_TextEncoding directly
-    paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
+    SkUnichar unichar = unicode;
+
     uint16_t glyph16;
-    uint16_t unichar[2];
-    size_t size = SkUTF16_FromUnichar(unicode, unichar);
-    paint->textToGlyphs(unichar, size * sizeof(*unichar), &glyph16);
+    paint->textToGlyphs(&unichar, sizeof(unichar), &glyph16);
     *glyph = glyph16;
     return !!*glyph;
 }
diff --git a/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp b/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp
index 7a3c598..14badb7 100644
--- a/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp
+++ b/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp
@@ -43,12 +43,13 @@
     return env;
 }
 
-static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener) {
+static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener, jint id) {
     class AnimationListenerBridge : public AnimationListener {
     public:
-        AnimationListenerBridge(JNIEnv* env, jobject finishListener) {
+        AnimationListenerBridge(JNIEnv* env, jobject finishListener, jint id) {
             mFinishListener = env->NewGlobalRef(finishListener);
             env->GetJavaVM(&mJvm);
+            mId = id;
         }
 
         virtual ~AnimationListenerBridge() {
@@ -63,7 +64,7 @@
             env->CallStaticVoidMethod(
                     gVectorDrawableAnimatorClassInfo.clazz,
                     gVectorDrawableAnimatorClassInfo.callOnFinished,
-                    mFinishListener);
+                    mFinishListener, mId);
             releaseJavaObject();
         }
 
@@ -76,8 +77,9 @@
 
         JavaVM* mJvm;
         jobject mFinishListener;
+        jint mId;
     };
-    return new AnimationListenerBridge(env, finishListener);
+    return new AnimationListenerBridge(env, finishListener, id);
 }
 
 static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
@@ -142,15 +144,16 @@
     holder->setPropertyDataSource(propertyData, length);
     env->ReleaseFloatArrayElements(srcData, propertyData, JNI_ABORT);
 }
-static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener) {
+static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
     PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
-    // TODO: keep a ref count in finish listener
-    AnimationListener* listener = createAnimationListener(env, finishListener);
+    AnimationListener* listener = createAnimationListener(env, finishListener, id);
     set->start(listener);
 }
 
-static void reverse(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener) {
-    // TODO: implement reverse
+static void reverse(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
+    PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
+    AnimationListener* listener = createAnimationListener(env, finishListener, id);
+    set->reverse(listener);
 }
 
 static void end(JNIEnv*, jobject, jlong animatorSetPtr) {
@@ -172,8 +175,8 @@
     {"nCreatePathPropertyHolder", "!(JIFF)J", (void*)createPathPropertyHolder},
     {"nCreateRootAlphaPropertyHolder", "!(JFF)J", (void*)createRootAlphaPropertyHolder},
     {"nSetPropertyHolderData", "(J[FI)V", (void*)setPropertyHolderData},
-    {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V", (void*)start},
-    {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V", (void*)reverse},
+    {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;I)V", (void*)start},
+    {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;I)V", (void*)reverse},
     {"nEnd", "!(J)V", (void*)end},
     {"nReset", "!(J)V", (void*)reset},
 };
@@ -186,7 +189,7 @@
 
     gVectorDrawableAnimatorClassInfo.callOnFinished = GetStaticMethodIDOrDie(
             env, gVectorDrawableAnimatorClassInfo.clazz, "callOnFinished",
-            "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V");
+            "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;I)V");
     return RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedVectorDrawable",
             gMethods, NELEM(gMethods));
 }
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index ba0876d..defb88a 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -39,23 +39,6 @@
 int ifc_enable(const char *ifname);
 int ifc_disable(const char *ifname);
 int ifc_reset_connections(const char *ifname, int reset_mask);
-
-int dhcp_start(const char * const ifname);
-int dhcp_start_renew(const char * const ifname);
-int dhcp_get_results(const char * const ifname,
-                     const char *ipaddr,
-                     const char *gateway,
-                     uint32_t *prefixLength,
-                     const char *dns[],
-                     const char *server,
-                     uint32_t *lease,
-                     const char *vendorInfo,
-                     const char *domains,
-                     const char *mtu);
-
-int dhcp_stop(const char *ifname);
-int dhcp_release_lease(const char *ifname);
-char *dhcp_get_errmsg();
 }
 
 #define NETUTILS_PKG_NAME "android/net/NetworkUtils"
@@ -64,22 +47,6 @@
 
 static const uint16_t kDhcpClientPort = 68;
 
-/*
- * The following remembers the jfieldID's of the fields
- * of the DhcpInfo Java object, so that we don't have
- * to look them up every time.
- */
-static struct fieldIds {
-    jmethodID clear;
-    jmethodID setIpAddress;
-    jmethodID setGateway;
-    jmethodID addDns;
-    jmethodID setDomains;
-    jmethodID setServerAddress;
-    jmethodID setLeaseDuration;
-    jmethodID setVendorInfo;
-} dhcpResultsFieldIds;
-
 static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
       jstring ifname, jint mask)
 {
@@ -95,137 +62,6 @@
     return (jint)result;
 }
 
-static jboolean android_net_utils_getDhcpResults(JNIEnv* env, jobject clazz, jstring ifname,
-        jobject dhcpResults)
-{
-    int result;
-    char  ipaddr[PROPERTY_VALUE_MAX];
-    uint32_t prefixLength;
-    char gateway[PROPERTY_VALUE_MAX];
-    char    dns1[PROPERTY_VALUE_MAX];
-    char    dns2[PROPERTY_VALUE_MAX];
-    char    dns3[PROPERTY_VALUE_MAX];
-    char    dns4[PROPERTY_VALUE_MAX];
-    const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
-    char  server[PROPERTY_VALUE_MAX];
-    uint32_t lease;
-    char vendorInfo[PROPERTY_VALUE_MAX];
-    char domains[PROPERTY_VALUE_MAX];
-    char mtu[PROPERTY_VALUE_MAX];
-
-    const char *nameStr = env->GetStringUTFChars(ifname, NULL);
-    if (nameStr == NULL) return (jboolean)false;
-
-    result = ::dhcp_get_results(nameStr, ipaddr, gateway, &prefixLength,
-            dns, server, &lease, vendorInfo, domains, mtu);
-    if (result != 0) {
-        ALOGD("dhcp_get_results failed : %s (%s)", nameStr, ::dhcp_get_errmsg());
-    }
-
-    env->ReleaseStringUTFChars(ifname, nameStr);
-    if (result == 0) {
-        env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
-
-        // set the linkAddress
-        // dhcpResults->addLinkAddress(inetAddress, prefixLength)
-        result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setIpAddress,
-                env->NewStringUTF(ipaddr), prefixLength);
-    }
-
-    if (result == 0) {
-        // set the gateway
-        result = env->CallBooleanMethod(dhcpResults,
-                dhcpResultsFieldIds.setGateway, env->NewStringUTF(gateway));
-    }
-
-    if (result == 0) {
-        // dhcpResults->addDns(new InetAddress(dns1))
-        result = env->CallBooleanMethod(dhcpResults,
-                dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
-    }
-
-    if (result == 0) {
-        env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
-                env->NewStringUTF(domains));
-
-        result = env->CallBooleanMethod(dhcpResults,
-                dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
-
-        if (result == 0) {
-            result = env->CallBooleanMethod(dhcpResults,
-                    dhcpResultsFieldIds.addDns, env->NewStringUTF(dns3));
-            if (result == 0) {
-                result = env->CallBooleanMethod(dhcpResults,
-                        dhcpResultsFieldIds.addDns, env->NewStringUTF(dns4));
-            }
-        }
-    }
-
-    if (result == 0) {
-        // dhcpResults->setServerAddress(new InetAddress(server))
-        result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
-                env->NewStringUTF(server));
-    }
-
-    if (result == 0) {
-        // dhcpResults->setLeaseDuration(lease)
-        env->CallVoidMethod(dhcpResults,
-                dhcpResultsFieldIds.setLeaseDuration, lease);
-
-        // dhcpResults->setVendorInfo(vendorInfo)
-        env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setVendorInfo,
-                env->NewStringUTF(vendorInfo));
-    }
-    return (jboolean)(result == 0);
-}
-
-static jboolean android_net_utils_startDhcp(JNIEnv* env, jobject clazz, jstring ifname)
-{
-    const char *nameStr = env->GetStringUTFChars(ifname, NULL);
-    if (nameStr == NULL) return (jboolean)false;
-    if (::dhcp_start(nameStr) != 0) {
-        ALOGD("dhcp_start failed : %s", nameStr);
-        return (jboolean)false;
-    }
-    return (jboolean)true;
-}
-
-static jboolean android_net_utils_startDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname)
-{
-    const char *nameStr = env->GetStringUTFChars(ifname, NULL);
-    if (nameStr == NULL) return (jboolean)false;
-    if (::dhcp_start_renew(nameStr) != 0) {
-        ALOGD("dhcp_start_renew failed : %s", nameStr);
-        return (jboolean)false;
-    }
-    return (jboolean)true;
-}
-
-static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
-{
-    int result;
-
-    const char *nameStr = env->GetStringUTFChars(ifname, NULL);
-    result = ::dhcp_stop(nameStr);
-    env->ReleaseStringUTFChars(ifname, nameStr);
-    return (jboolean)(result == 0);
-}
-
-static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
-{
-    int result;
-
-    const char *nameStr = env->GetStringUTFChars(ifname, NULL);
-    result = ::dhcp_release_lease(nameStr);
-    env->ReleaseStringUTFChars(ifname, nameStr);
-    return (jboolean)(result == 0);
-}
-
-static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
-{
-    return env->NewStringUTF(::dhcp_get_errmsg());
-}
-
 static void android_net_utils_attachDhcpFilter(JNIEnv *env, jobject clazz, jobject javaFd)
 {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -305,12 +141,6 @@
 static const JNINativeMethod gNetworkUtilMethods[] = {
     /* name, signature, funcPtr */
     { "resetConnections", "(Ljava/lang/String;I)I",  (void *)android_net_utils_resetConnections },
-    { "startDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_startDhcp },
-    { "startDhcpRenew", "(Ljava/lang/String;)Z",  (void *)android_net_utils_startDhcpRenew },
-    { "getDhcpResults", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z",  (void *)android_net_utils_getDhcpResults },
-    { "stopDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_stopDhcp },
-    { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
-    { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
     { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork },
     { "getBoundNetworkForProcess", "()I", (void*) android_net_utils_getBoundNetworkForProcess },
     { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
@@ -322,24 +152,6 @@
 
 int register_android_net_NetworkUtils(JNIEnv* env)
 {
-    jclass dhcpResultsClass = FindClassOrDie(env, "android/net/DhcpResults");
-
-    dhcpResultsFieldIds.clear = GetMethodIDOrDie(env, dhcpResultsClass, "clear", "()V");
-    dhcpResultsFieldIds.setIpAddress =GetMethodIDOrDie(env, dhcpResultsClass, "setIpAddress",
-            "(Ljava/lang/String;I)Z");
-    dhcpResultsFieldIds.setGateway = GetMethodIDOrDie(env, dhcpResultsClass, "setGateway",
-            "(Ljava/lang/String;)Z");
-    dhcpResultsFieldIds.addDns = GetMethodIDOrDie(env, dhcpResultsClass, "addDns",
-            "(Ljava/lang/String;)Z");
-    dhcpResultsFieldIds.setDomains = GetMethodIDOrDie(env, dhcpResultsClass, "setDomains",
-            "(Ljava/lang/String;)V");
-    dhcpResultsFieldIds.setServerAddress = GetMethodIDOrDie(env, dhcpResultsClass,
-            "setServerAddress", "(Ljava/lang/String;)Z");
-    dhcpResultsFieldIds.setLeaseDuration = GetMethodIDOrDie(env, dhcpResultsClass,
-            "setLeaseDuration", "(I)V");
-    dhcpResultsFieldIds.setVendorInfo = GetMethodIDOrDie(env, dhcpResultsClass, "setVendorInfo",
-            "(Ljava/lang/String;)V");
-
     return RegisterMethodsOrDie(env, NETUTILS_PKG_NAME, gNetworkUtilMethods,
                                 NELEM(gNetworkUtilMethods));
 }
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index 0926e9b..c9eac79 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -184,7 +184,7 @@
 
 static void end(JNIEnv* env, jobject clazz, jlong animatorPtr) {
     BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
-    animator->end();
+    animator->cancel();
 }
 
 // ----------------------------------------------------------------------------
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index cd2c0d6..07868c5 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -164,6 +164,13 @@
         mPendingAnimatingRenderNodes.clear();
     }
 
+    void destroy() {
+        for (auto& renderNode : mPendingAnimatingRenderNodes) {
+            renderNode->animators().endAllStagingAnimators();
+        }
+        mPendingAnimatingRenderNodes.clear();
+    }
+
 private:
     sp<Looper> mLooper;
     JavaVM* mVm;
@@ -476,7 +483,9 @@
 }
 
 static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
-        jlong proxyPtr) {
+        jlong proxyPtr, jlong rootNodePtr) {
+    RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
+    rootRenderNode->destroy();
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
     proxy->destroy();
 }
@@ -698,7 +707,7 @@
     { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
     { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
     { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
-    { "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy },
+    { "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
     { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
     { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
     { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 4194aa4..612f4df 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -608,8 +608,12 @@
     jlong capabilities = 0;
 
     // Grant CAP_WAKE_ALARM to the Bluetooth process.
+    // Additionally, allow bluetooth to open packet sockets so it can start the DHCP client.
+    // TODO: consider making such functionality an RPC to netd.
     if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
       capabilities |= (1LL << CAP_WAKE_ALARM);
+      capabilities |= (1LL << CAP_NET_RAW);
+      capabilities |= (1LL << CAP_NET_BIND_SERVICE);
     }
 
     // Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9b989b9..eeff00f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -452,6 +452,8 @@
     <protected-broadcast android:name="android.bluetooth.input.profile.action.HANDSHAKE" />
     <protected-broadcast android:name="android.bluetooth.input.profile.action.REPORT" />
 
+    <protected-broadcast android:name="android.intent.action.TWILIGHT_CHANGED" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -2006,6 +2008,12 @@
     <permission android:name="android.permission.UPDATE_APP_OPS_STATS"
         android:protectionLevel="signature|privileged|installer" />
 
+    <!-- Allows an application to update the user app op restrictions.
+         Not for use by third party apps.
+         @hide -->
+    <permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS"
+        android:protectionLevel="signature|installer" />
+
     <!-- @SystemApi Allows an application to open windows that are for use by parts
          of the system user interface.
          <p>Not for use by third-party applications.
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index aa78eff..a5ed187 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -19,41 +19,45 @@
 <com.android.internal.widget.MediaNotificationView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
-    android:layout_height="126dp"
+    android:layout_height="wrap_content"
     android:background="#00000000"
     android:tag="bigMediaNarrow"
     >
     <include layout="@layout/notification_template_header"
         android:layout_width="match_parent"
         android:layout_height="48dp"
-        android:layout_alignParentStart="true"/>
+        android:layout_gravity="start"/>
     <LinearLayout
-        android:id="@+id/notification_main_column"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/notification_content_margin_top"
-        android:layout_marginStart="@dimen/notification_content_margin_start"
-        android:layout_marginBottom="@dimen/notification_content_margin_bottom"
-        android:layout_marginEnd="@dimen/notification_content_margin_end"
-        android:layout_toStartOf="@id/right_icon"
-        android:minHeight="@dimen/notification_min_content_height"
         android:orientation="vertical"
         >
-        <include layout="@layout/notification_template_part_line1" />
-        <include layout="@layout/notification_template_text" />
-    </LinearLayout>
-    <LinearLayout
-        android:id="@+id/media_actions"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentStart="true"
-        android:paddingStart="8dp"
-        android:paddingBottom="8dp"
-        android:orientation="horizontal"
-        android:layoutDirection="ltr"
-        >
-        <!-- media buttons will be added here -->
+        <LinearLayout
+            android:id="@+id/notification_main_column"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/notification_content_margin_top"
+            android:layout_marginStart="@dimen/notification_content_margin_start"
+            android:layout_marginBottom="@dimen/notification_content_margin_bottom"
+            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:minHeight="@dimen/notification_min_content_height"
+            android:orientation="vertical"
+            >
+            <include layout="@layout/notification_template_part_line1" />
+            <include layout="@layout/notification_template_text" />
+        </LinearLayout>
+        <LinearLayout
+            android:id="@+id/media_actions"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="-15dp"
+            android:paddingStart="8dp"
+            android:paddingBottom="8dp"
+            android:orientation="horizontal"
+            android:layoutDirection="ltr"
+            >
+            <!-- media buttons will be added here -->
+        </LinearLayout>
     </LinearLayout>
 
     <ImageView android:id="@+id/right_icon"
@@ -61,9 +65,8 @@
         android:layout_height="@dimen/media_notification_expanded_image_max_size"
         android:minWidth="40dp"
         android:layout_marginEnd="16dp"
-        android:layout_marginTop="16dp"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentTop="true"
+        android:layout_marginBottom="16dp"
+        android:layout_gravity="bottom|end"
         android:scaleType="centerCrop"
         />
 </com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index aea9b44..cda0636 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -36,6 +36,7 @@
         android:tag="media"
         >
         <LinearLayout
+            android:id="@+id/notification_content_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="fill_vertical"
@@ -45,7 +46,6 @@
             android:orientation="vertical"
             >
             <include layout="@layout/notification_template_part_line1"/>
-            <include layout="@layout/notification_template_progress"/>
             <include layout="@layout/notification_template_text"/>
         </LinearLayout>
         <LinearLayout
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 016ed60..3a185d6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1992,10 +1992,10 @@
      See {@link com.android.server.notification.NotificationSignalExtractor} -->
     <string-array name="config_notificationSignalExtractors">
         <item>com.android.server.notification.ValidateNotificationPeople</item>
-        <item>com.android.server.notification.TopicPriorityExtractor</item>
-        <item>com.android.server.notification.TopicImportanceExtractor</item>
+        <item>com.android.server.notification.PriorityExtractor</item>
+        <item>com.android.server.notification.ImportanceExtractor</item>
         <item>com.android.server.notification.NotificationIntrusivenessExtractor</item>
-        <item>com.android.server.notification.TopicVisibilityExtractor</item>
+        <item>com.android.server.notification.VisibilityExtractor</item>
     </string-array>
 
     <!-- Flag indicating that this device does not rotate and will always remain in its default
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 8e86f78..1005704 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -56,6 +56,10 @@
          calculate the bounds of the stacks-->
     <dimen name="docked_stack_divider_insets">19dp</dimen>
 
+    <!-- To how much the docked stack gets reduced when we decide to minimize the docked stack, i.e.
+         when the user opens homescreen. -->
+    <dimen name="docked_stack_minimize_thickness">8dp</dimen>
+
     <!-- Min width for a tablet device -->
     <dimen name="min_xlarge_screen_width">800dp</dimen>
 
@@ -146,9 +150,6 @@
     <!-- The margin on the end of the content view with a picture.-->
     <dimen name="notification_content_picture_margin">56dp</dimen>
 
-    <!-- The margin on the end of the content view with a picture in the compact media.-->
-    <dimen name="notification_content_picture_margin_media">72dp</dimen>
-
     <!-- height of the content margin to accomodate for the header -->
     <dimen name="notification_content_margin_top">30dp</dimen>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1f0e96d..da88146 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4162,9 +4162,7 @@
         <item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> selected</item>
     </plurals>
 
-    <string name="default_notification_topic_label">Miscellaneous</string>
-
-    <string name="importance_from_topic">You set the importance of these notifications.</string>
+    <string name="importance_from_user">You set the importance of these notifications.</string>
     <string name="importance_from_person">This is important because of the people involved.</string>
 
     <!-- Message to user that app trying to create user for an account that already exists. [CHAR LIMIT=none] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2d3ad17..746e7fd 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1506,6 +1506,7 @@
   <java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
   <java-symbol type="dimen" name="docked_stack_divider_thickness" />
   <java-symbol type="dimen" name="docked_stack_divider_insets" />
+  <java-symbol type="dimen" name="docked_stack_minimize_thickness" />
   <java-symbol type="integer" name="config_dockedStackDividerSnapMode" />
   <java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" />
   <java-symbol type="dimen" name="navigation_bar_height" />
@@ -2388,7 +2389,6 @@
   <java-symbol type="string" name="config_iccHotswapPromptForRestartDialogComponent" />
 
   <java-symbol type="string" name="config_packagedKeyboardName" />
-  <java-symbol type="string" name="default_notification_topic_label" />
   <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" />
   <java-symbol type="color" name="system_bar_background_semi_transparent" />
 
@@ -2427,7 +2427,7 @@
   <java-symbol type="dimen" name="notification_content_margin_end" />
   <java-symbol type="dimen" name="notification_content_picture_margin" />
   <java-symbol type="dimen" name="notification_content_margin_top" />
-  <java-symbol type="string" name="importance_from_topic" />
+  <java-symbol type="string" name="importance_from_user" />
   <java-symbol type="string" name="importance_from_person" />
 
   <java-symbol type="layout" name="work_widget_mask_view" />
@@ -2512,13 +2512,14 @@
   <java-symbol type="dimen" name="media_notification_expanded_image_max_size" />
   <java-symbol type="dimen" name="media_notification_expanded_image_margin_bottom" />
   <java-symbol type="dimen" name="notification_content_image_margin_end" />
-  <java-symbol type="dimen" name="notification_content_picture_margin_media" />
 
   <java-symbol type="bool" name="config_strongAuthRequiredOnBoot" />
 
   <java-symbol type="layout" name="app_anr_dialog" />
   <java-symbol type="id" name="aerr_wait" />
 
+  <java-symbol type="id" name="notification_content_container" />
+
   <!-- Encryption notification while accounts are locked by credential encryption -->
   <java-symbol type="string" name="user_encrypted_title" />
   <java-symbol type="string" name="user_encrypted_message" />
diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk
index 7322e8d..9e45d09 100644
--- a/core/tests/coretests/apks/install_jni_lib/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib/Android.mk
@@ -22,6 +22,8 @@
 LOCAL_SHARED_LIBRARIES := \
     libnativehelper
 
+LOCAL_CFLAGS += -Wall -Werror
+
 LOCAL_MODULE := libframeworks_coretests_jni
 
 # this does not prevent build system
diff --git a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
index 3e83010..8d91192 100644
--- a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
+++ b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
@@ -37,7 +37,7 @@
 /*
  * JNI Initialization
  */
-jint JNI_OnLoad(JavaVM *jvm, void *reserved) {
+jint JNI_OnLoad(JavaVM *jvm, void */* reserved */) {
     JNIEnv *e;
     int status;
 
diff --git a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk
index ff5a535..994131a 100644
--- a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk
+++ b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk
@@ -32,6 +32,8 @@
 # All of the shard libraries we link against.
 LOCAL_SHARED_LIBRARIES := liblog
 
+LOCAL_CFLAGS += -Wall -Wextra -Werror
+
 # Also need the JNI headers.
 LOCAL_C_INCLUDES += \
 	$(JNI_H_INCLUDE)
diff --git a/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp
index 67b12d7..99cf587 100644
--- a/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp
+++ b/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp
@@ -22,7 +22,7 @@
 #include "jni.h"
 
 static jint
-add(JNIEnv *env, jobject thiz, jint a, jint b) {
+add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) {
 int result = a + b;
     ALOGI("%d + %d = %d", a, b, result);
     return result;
@@ -82,7 +82,7 @@
     void* venv;
 } UnionJNIEnvToVoid;
 
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
 {
     UnionJNIEnvToVoid uenv;
     uenv.venv = NULL;
diff --git a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk
index abb1d9f..6c2679b 100644
--- a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk
+++ b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk
@@ -34,6 +34,8 @@
 LOCAL_SHARED_LIBRARIES := \
 	libutils liblog
 
+LOCAL_CFLAGS += -Wall -Wextra -Werror
+
 # Also need the JNI headers.
 LOCAL_C_INCLUDES += \
 	$(JNI_H_INCLUDE)
diff --git a/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp
index 342b3bc..0b6d750 100644
--- a/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp
+++ b/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp
@@ -22,7 +22,7 @@
 #include "jni.h"
 
 static jint
-add(JNIEnv *env, jobject thiz, jint a, jint b) {
+add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) {
 int result = a + b;
     ALOGI("%d + %d = %d", a, b, result);
     return result;
@@ -82,7 +82,7 @@
     void* venv;
 } UnionJNIEnvToVoid;
 
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
 {
     UnionJNIEnvToVoid uenv;
     uenv.venv = NULL;
diff --git a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk
index ae8e636..d668f29 100644
--- a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk
+++ b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk
@@ -33,6 +33,8 @@
 LOCAL_LDLIBS = -llog
 LOCAL_SHARED_LIBRARIES := liblog
 
+LOCAL_CFLAGS += -Wall -Wextra -Werror
+
 # Also need the JNI headers.
 LOCAL_C_INCLUDES += \
 	$(JNI_H_INCLUDE)
diff --git a/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp
index 9b38e3e..3947e21 100644
--- a/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp
+++ b/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp
@@ -22,7 +22,7 @@
 #include "jni.h"
 
 static jint
-add(JNIEnv *env, jobject thiz, jint a, jint b) {
+add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) {
 int result = a + b;
     ALOGI("%d + %d = %d", a, b, result);
     return result;
@@ -82,7 +82,7 @@
     void* venv;
 } UnionJNIEnvToVoid;
 
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
 {
     UnionJNIEnvToVoid uenv;
     uenv.venv = NULL;
diff --git a/core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java b/core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java
deleted file mode 100644
index 7088650..0000000
--- a/core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright (C) 2010 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.internal.util;
-
-import android.os.Debug;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import junit.framework.TestCase;
-
-/**
- * Test for AsyncChannel.
- */
-public class AsyncChannelTest extends TestCase {
-    private static final boolean DBG = true;
-    private static final boolean WAIT_FOR_DEBUGGER = false;
-    private static final String TAG = "AsyncChannelTest";
-
-    @SmallTest
-    public void test1() throws Exception {
-        if (DBG) log("test1");
-        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
-        assertTrue(1 == 1);
-    }
-
-    protected void log(String s) {
-        Log.d(TAG, s);
-    }
-}
diff --git a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
index be7116d..5f36c2d 100644
--- a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
@@ -42,6 +42,6 @@
         out.endDocument();
 
         assertEquals("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
-                + "<string name=\"meow\"></string>", stream.toString());
+                + "<string name=\"meow\"></string>\n", stream.toString());
     }
 }
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index af8ccf5..c486c1f 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -154,7 +154,7 @@
     private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
 
     /** Local, mutable animator set. */
-    private final VectorDrawableAnimator mAnimatorSet = new VectorDrawableAnimator();
+    private final VectorDrawableAnimator mAnimatorSet = new VectorDrawableAnimator(this);
 
     /**
      * The resources against which this drawable was created. Used to attempt
@@ -238,9 +238,6 @@
             mAnimatorSet.recordLastSeenTarget((DisplayListCanvas) canvas);
         }
         mAnimatedVectorState.mVectorDrawable.draw(canvas);
-        if (isStarted()) {
-            invalidateSelf();
-        }
     }
 
     @Override
@@ -611,29 +608,17 @@
         return mAnimatorSet.isRunning();
     }
 
-    private boolean isStarted() {
-        return mAnimatorSet.isStarted();
-    }
-
     /**
      * Resets the AnimatedVectorDrawable to the start state as specified in the animators.
      */
     public void reset() {
         mAnimatorSet.reset();
-        invalidateSelf();
     }
 
     @Override
     public void start() {
         ensureAnimatorSet();
-
-        // If any one of the animator has not ended, do nothing.
-        if (isStarted()) {
-            return;
-        }
-
         mAnimatorSet.start();
-        invalidateSelf();
     }
 
     @NonNull
@@ -671,7 +656,6 @@
         }
 
         mAnimatorSet.reverse();
-        invalidateSelf();
     }
 
     /**
@@ -774,6 +758,9 @@
      * @hide
      */
     public static class VectorDrawableAnimator {
+        private static final int NONE = 0;
+        private static final int START_ANIMATION = 1;
+        private static final int REVERSE_ANIMATION = 2;
         private AnimatorListener mListener = null;
         private final LongArray mStartDelays = new LongArray();
         private PropertyValuesHolder.PropertyValues mTmpValues =
@@ -782,17 +769,18 @@
         private boolean mContainsSequentialAnimators = false;
         private boolean mStarted = false;
         private boolean mInitialized = false;
-        private boolean mAnimationPending = false;
         private boolean mIsReversible = false;
         // This needs to be set before parsing starts.
         private boolean mShouldIgnoreInvalidAnim;
         // TODO: Consider using NativeAllocationRegistery to track native allocation
         private final VirtualRefBasePtr mSetRefBasePtr;
-        private WeakReference<RenderNode> mTarget = null;
         private WeakReference<RenderNode> mLastSeenTarget = null;
+        private int mLastListenerId = 0;
+        private int mPendingAnimationAction = NONE;
+        private final Drawable mDrawable;
 
-
-        VectorDrawableAnimator() {
+        VectorDrawableAnimator(AnimatedVectorDrawable drawable) {
+            mDrawable = drawable;
             mSetPtr = nCreateAnimatorSet();
             // Increment ref count on native AnimatorSet, so it doesn't get released before Java
             // side is done using it.
@@ -810,6 +798,7 @@
             mInitialized = true;
 
             // Check reversible.
+            mIsReversible = true;
             if (mContainsSequentialAnimators) {
                 mIsReversible = false;
             } else {
@@ -821,7 +810,6 @@
                     }
                 }
             }
-            mIsReversible = true;
         }
 
         private void parseAnimatorSet(AnimatorSet set, long startTime) {
@@ -1042,51 +1030,44 @@
          * to the last seen RenderNode target and start right away.
          */
         protected void recordLastSeenTarget(DisplayListCanvas canvas) {
-            if (mAnimationPending) {
-                mLastSeenTarget = new WeakReference<RenderNode>(
-                        RenderNodeAnimatorSetHelper.getTarget(canvas));
+            mLastSeenTarget = new WeakReference<RenderNode>(
+                    RenderNodeAnimatorSetHelper.getTarget(canvas));
+            if (mPendingAnimationAction != NONE) {
                 if (DBG_ANIMATION_VECTOR_DRAWABLE) {
                     Log.d(LOGTAG, "Target is set in the next frame");
                 }
-                mAnimationPending = false;
-                start();
-            } else {
-                mLastSeenTarget = new WeakReference<RenderNode>(
-                        RenderNodeAnimatorSetHelper.getTarget(canvas));
+                if (mPendingAnimationAction == START_ANIMATION) {
+                    start();
+                } else if (mPendingAnimationAction == REVERSE_ANIMATION) {
+                    reverse();
+                }
+                mPendingAnimationAction = NONE;
             }
-
-        }
-
-        private boolean setTarget(RenderNode node) {
-            if (mTarget != null && mTarget.get() != null) {
-                // TODO: Maybe we want to support target change.
-                throw new IllegalStateException("Target already set!");
-            }
-
-            node.addAnimator(this);
-            mTarget = new WeakReference<RenderNode>(node);
-            return true;
         }
 
         private boolean useLastSeenTarget() {
-            if (mLastSeenTarget != null && mLastSeenTarget.get() != null) {
-                setTarget(mLastSeenTarget.get());
-                return true;
+            if (mLastSeenTarget != null) {
+                final RenderNode target = mLastSeenTarget.get();
+                if (target != null && target.isAttached()) {
+                    target.addAnimator(this);
+                    return true;
+                }
             }
             return false;
         }
 
+        private void invalidateOwningView() {
+            mDrawable.invalidateSelf();
+        }
+
         public void start() {
             if (!mInitialized) {
                 return;
             }
 
-            if (mStarted) {
-                return;
-            }
-
             if (!useLastSeenTarget()) {
-                mAnimationPending = true;
+                invalidateOwningView();
+                mPendingAnimationAction = START_ANIMATION;
                 return;
             }
 
@@ -1094,38 +1075,50 @@
                 Log.d(LOGTAG, "Target is set. Starting VDAnimatorSet from java");
             }
 
-           nStart(mSetPtr, this);
+            mStarted = true;
+            nStart(mSetPtr, this, ++mLastListenerId);
+            invalidateOwningView();
             if (mListener != null) {
                 mListener.onAnimationStart(null);
             }
-            mStarted = true;
         }
 
         public void end() {
-            if (mInitialized && mStarted) {
+            if (mInitialized && useLastSeenTarget()) {
+                // If no target has ever been set, no-op
                 nEnd(mSetPtr);
-                onAnimationEnd();
+                invalidateOwningView();
             }
         }
 
-        void reset() {
-            if (!mInitialized) {
-                return;
+        public void reset() {
+            if (mInitialized && useLastSeenTarget()) {
+                // If no target has ever been set, no-op
+                nReset(mSetPtr);
+                invalidateOwningView();
             }
-            // TODO: Need to implement reset.
-            Log.w(LOGTAG, "Reset is yet to be implemented");
-            nReset(mSetPtr);
         }
 
         // Current (imperfect) Java AnimatorSet cannot be reversed when the set contains sequential
         // animators or when the animator set has a start delay
         void reverse() {
-            if (!mIsReversible) {
+            if (!mIsReversible || !mInitialized) {
                 return;
             }
-            // TODO: Need to support reverse (non-public API)
-            Log.w(LOGTAG, "Reverse is yet to be implemented");
-            nReverse(mSetPtr, this);
+            if (!useLastSeenTarget()) {
+                invalidateOwningView();
+                mPendingAnimationAction = REVERSE_ANIMATION;
+                return;
+            }
+            if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+                Log.d(LOGTAG, "Target is set. Reversing VDAnimatorSet from java");
+            }
+            mStarted = true;
+            nReverse(mSetPtr, this, ++mLastListenerId);
+            invalidateOwningView();
+            if (mListener != null) {
+                mListener.onAnimationStart(null);
+            }
         }
 
         public long getAnimatorNativePtr() {
@@ -1155,20 +1148,22 @@
             mListener = null;
         }
 
-        private void onAnimationEnd() {
+        private void onAnimationEnd(int listenerId) {
+            if (listenerId != mLastListenerId) {
+                return;
+            }
+            if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+                Log.d(LOGTAG, "on finished called from native");
+            }
             mStarted = false;
             if (mListener != null) {
                 mListener.onAnimationEnd(null);
             }
-            mTarget = null;
         }
 
         // onFinished: should be called from native
-        private static void callOnFinished(VectorDrawableAnimator set) {
-            if (DBG_ANIMATION_VECTOR_DRAWABLE) {
-                Log.d(LOGTAG, "on finished called from native");
-            }
-            set.onAnimationEnd();
+        private static void callOnFinished(VectorDrawableAnimator set, int id) {
+            set.onAnimationEnd(id);
         }
     }
 
@@ -1188,8 +1183,8 @@
     private static native long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
             float endValue);
     private static native void nSetPropertyHolderData(long nativePtr, float[] data, int length);
-    private static native void nStart(long animatorSetPtr, VectorDrawableAnimator set);
-    private static native void nReverse(long animatorSetPtr, VectorDrawableAnimator set);
+    private static native void nStart(long animatorSetPtr, VectorDrawableAnimator set, int id);
+    private static native void nReverse(long animatorSetPtr, VectorDrawableAnimator set, int id);
     private static native void nEnd(long animatorSetPtr);
     private static native void nReset(long animatorSetPtr);
 }
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 6257122..8660b75 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -7,7 +7,7 @@
 # Enables fine-grained GLES error checking
 # If set to true, every GLES call is wrapped & error checked
 # Has moderate overhead
-HWUI_ENABLE_OPENGL_VALIDATION := false
+HWUI_ENABLE_OPENGL_VALIDATION := true
 
 hwui_src_files := \
     font/CacheTexture.cpp \
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 7bd2b24..294edb6 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -33,6 +33,7 @@
 
 BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
         : mTarget(nullptr)
+        , mStagingTarget(nullptr)
         , mFinalValue(finalValue)
         , mDeltaValue(0)
         , mFromValue(0)
@@ -42,7 +43,8 @@
         , mStartTime(0)
         , mDuration(300)
         , mStartDelay(0)
-        , mMayRunAsync(true) {
+        , mMayRunAsync(true)
+        , mPlayTime(0) {
 }
 
 BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
@@ -81,26 +83,129 @@
 }
 
 void BaseRenderNodeAnimator::attach(RenderNode* target) {
-    mTarget = target;
+    mStagingTarget = target;
     onAttached();
 }
 
+void BaseRenderNodeAnimator::start() {
+    mStagingPlayState = PlayState::Running;
+    mStagingRequests.push_back(Request::Start);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::cancel() {
+    mStagingPlayState = PlayState::Finished;
+    mStagingRequests.push_back(Request::Cancel);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::reset() {
+    mStagingPlayState = PlayState::Finished;
+    mStagingRequests.push_back(Request::Reset);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::reverse() {
+    mStagingPlayState = PlayState::Reversing;
+    mStagingRequests.push_back(Request::Reverse);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::end() {
+    mStagingPlayState = PlayState::Finished;
+    mStagingRequests.push_back(Request::End);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::resolveStagingRequest(Request request) {
+    switch (request) {
+    case Request::Start:
+        mPlayTime = (mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) ?
+                        mPlayTime : 0;
+        mPlayState = PlayState::Running;
+        break;
+    case Request::Reverse:
+        mPlayTime = (mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) ?
+                        mPlayTime : mDuration;
+        mPlayState = PlayState::Reversing;
+        break;
+    case Request::Reset:
+        mPlayTime = 0;
+        mPlayState = PlayState::Finished;
+        break;
+    case Request::Cancel:
+        mPlayState = PlayState::Finished;
+        break;
+    case Request::End:
+        mPlayTime = mPlayState == PlayState::Reversing ? 0 : mDuration;
+        mPlayState = PlayState::Finished;
+        break;
+    default:
+        LOG_ALWAYS_FATAL("Invalid staging request: %d", static_cast<int>(request));
+    };
+}
+
 void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) {
+    if (mStagingTarget) {
+        RenderNode* oldTarget = mTarget;
+        mTarget = mStagingTarget;
+        mStagingTarget = nullptr;
+        if (oldTarget && oldTarget != mTarget) {
+            oldTarget->onAnimatorTargetChanged(this);
+        }
+    }
+
     if (!mHasStartValue) {
         doSetStartValue(getValue(mTarget));
     }
-    if (mStagingPlayState > mPlayState) {
-        if (mStagingPlayState == PlayState::Restarted) {
-            mStagingPlayState = PlayState::Running;
+
+    if (!mStagingRequests.empty()) {
+        // Keep track of the play state and play time before they are changed when
+        // staging requests are resolved.
+        nsecs_t currentPlayTime = mPlayTime;
+        PlayState prevFramePlayState = mPlayState;
+
+        // Resolve staging requests one by one.
+        for (Request request : mStagingRequests) {
+            resolveStagingRequest(request);
         }
-        mPlayState = mStagingPlayState;
-        // Oh boy, we're starting! Man the battle stations!
-        if (mPlayState == PlayState::Running) {
-            transitionToRunning(context);
-        } else if (mPlayState == PlayState::Finished) {
+        mStagingRequests.clear();
+
+        if (mStagingPlayState == PlayState::Finished) {
+            // Set the staging play time and end the animation
+            updatePlayTime(mPlayTime);
             callOnFinishedListener(context);
+        } else if (mStagingPlayState == PlayState::Running
+                || mStagingPlayState == PlayState::Reversing) {
+            bool changed = currentPlayTime != mPlayTime || prevFramePlayState != mStagingPlayState;
+            if (prevFramePlayState != mStagingPlayState) {
+                transitionToRunning(context);
+            }
+            if (changed) {
+                // Now we need to seek to the stagingPlayTime (i.e. the animation progress that was
+                // requested from UI thread). It is achieved by modifying mStartTime, such that
+                // current time - mStartTime = stagingPlayTime (or mDuration -stagingPlayTime in the
+                // case of reversing)
+                nsecs_t currentFrameTime = context.frameTimeMs();
+                if (mPlayState == PlayState::Reversing) {
+                    // Reverse is not supported for animations with a start delay, so here we
+                    // assume no start delay.
+                    mStartTime = currentFrameTime  - (mDuration - mPlayTime);
+                } else {
+                    // Animation should play forward
+                    if (mPlayTime == 0) {
+                        // If the request is to start from the beginning, include start delay.
+                        mStartTime = currentFrameTime + mStartDelay;
+                    } else {
+                        // If the request is to seek to a non-zero play time, then we skip start
+                        // delay.
+                        mStartTime = currentFrameTime - mPlayTime;
+                    }
+                }
+            }
         }
     }
+    onPushStaging();
 }
 
 void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) {
@@ -136,37 +241,37 @@
 
     // This should be set before setValue() so animators can query this time when setValue
     // is called.
-    nsecs_t currentFrameTime = context.frameTimeMs();
-    onPlayTimeChanged(currentFrameTime - mStartTime);
+    nsecs_t currentPlayTime = context.frameTimeMs() - mStartTime;
+    bool finished = updatePlayTime(currentPlayTime);
+    if (finished && mPlayState != PlayState::Finished) {
+        mPlayState = PlayState::Finished;
+        callOnFinishedListener(context);
+    }
+    return finished;
+}
 
+bool BaseRenderNodeAnimator::updatePlayTime(nsecs_t playTime) {
+    mPlayTime = mPlayState == PlayState::Reversing ? mDuration - playTime : playTime;
+    onPlayTimeChanged(mPlayTime);
     // If BaseRenderNodeAnimator is handling the delay (not typical), then
     // because the staging properties reflect the final value, we always need
     // to call setValue even if the animation isn't yet running or is still
     // being delayed as we need to override the staging value
-    if (mStartTime > context.frameTimeMs()) {
+    if (playTime < 0) {
         setValue(mTarget, mFromValue);
         return false;
     }
 
     float fraction = 1.0f;
-
-    if (mPlayState == PlayState::Running && mDuration > 0) {
-        fraction = (float)(currentFrameTime - mStartTime) / mDuration;
+    if ((mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) && mDuration > 0) {
+        fraction = mPlayTime / (float) mDuration;
     }
-    if (fraction >= 1.0f) {
-        fraction = 1.0f;
-        mPlayState = PlayState::Finished;
-    }
+    fraction = MathUtils::clamp(fraction, 0.0f, 1.0f);
 
     fraction = mInterpolator->interpolate(fraction);
     setValue(mTarget, mFromValue + (mDeltaValue * fraction));
 
-    if (mPlayState == PlayState::Finished) {
-        callOnFinishedListener(context);
-        return true;
-    }
-
-    return false;
+    return playTime >= mDuration;
 }
 
 void BaseRenderNodeAnimator::forceEndNow(AnimationContext& context) {
@@ -215,18 +320,36 @@
 
 void RenderPropertyAnimator::onAttached() {
     if (!mHasStartValue
-            && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
-        setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
+            && mStagingTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
+        setStartValue((mStagingTarget->stagingProperties().*mPropertyAccess->getter)());
     }
 }
 
 void RenderPropertyAnimator::onStagingPlayStateChanged() {
     if (mStagingPlayState == PlayState::Running) {
-        (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+        if (mStagingTarget) {
+            (mStagingTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+        } else {
+            // In the case of start delay where stagingTarget has been sync'ed over and null'ed
+            // we delay the properties update to push staging.
+            mShouldUpdateStagingProperties = true;
+        }
     } else if (mStagingPlayState == PlayState::Finished) {
         // We're being canceled, so make sure that whatever values the UI thread
         // is observing for us is pushed over
+        mShouldSyncPropertyFields = true;
+    }
+}
+
+void RenderPropertyAnimator::onPushStaging() {
+    if (mShouldUpdateStagingProperties) {
+        (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+        mShouldUpdateStagingProperties = false;
+    }
+
+    if (mShouldSyncPropertyFields) {
         mTarget->setPropertyFieldsDirty(dirtyMask());
+        mShouldSyncPropertyFields = false;
     }
 }
 
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 2c9c9c3..fdae0f3 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -24,6 +24,8 @@
 
 #include "utils/Macros.h"
 
+#include <vector>
+
 namespace android {
 namespace uirenderer {
 
@@ -59,14 +61,14 @@
         mMayRunAsync = mayRunAsync;
     }
     bool mayRunAsync() { return mMayRunAsync; }
-    ANDROID_API void start() {
-        if (mStagingPlayState == PlayState::NotStarted) {
-            mStagingPlayState = PlayState::Running;
-        } else {
-            mStagingPlayState = PlayState::Restarted;
-        }
-        onStagingPlayStateChanged(); }
-    ANDROID_API void end() { mStagingPlayState = PlayState::Finished; onStagingPlayStateChanged(); }
+    ANDROID_API void start();
+    ANDROID_API void reset();
+    ANDROID_API void reverse();
+    // Terminates the animation at its current progress.
+    ANDROID_API void cancel();
+
+    // Terminates the animation and skip to the end of the animation.
+    ANDROID_API void end();
 
     void attach(RenderNode* target);
     virtual void onAttached() {}
@@ -74,36 +76,42 @@
     void pushStaging(AnimationContext& context);
     bool animate(AnimationContext& context);
 
-    bool isRunning() { return mPlayState == PlayState::Running; }
+    bool isRunning() { return mPlayState == PlayState::Running
+            || mPlayState == PlayState::Reversing; }
     bool isFinished() { return mPlayState == PlayState::Finished; }
     float finalValue() { return mFinalValue; }
 
     ANDROID_API virtual uint32_t dirtyMask() = 0;
 
     void forceEndNow(AnimationContext& context);
+    RenderNode* target() { return mTarget; }
+    RenderNode* stagingTarget() { return mStagingTarget; }
 
 protected:
     // PlayState is used by mStagingPlayState and mPlayState to track the state initiated from UI
     // thread and Render Thread animation state, respectively.
     // From the UI thread, mStagingPlayState transition looks like
-    // NotStarted -> Running -> Finished
-    //                ^            |
-    //                |            |
-    //            Restarted <------
+    // NotStarted -> Running/Reversing -> Finished
+    //                ^                     |
+    //                |                     |
+    //                ----------------------
     // Note: For mStagingState, the Finished state (optional) is only set when the animation is
     // terminated by user.
     //
     // On Render Thread, mPlayState transition:
-    // NotStart -> Running -> Finished
-    //                ^            |
-    //                |            |
-    //                -------------
+    // NotStart -> Running/Reversing-> Finished
+    //                ^                 |
+    //                |                 |
+    //                ------------------
+    // Note that if the animation is in Running/Reversing state, calling start or reverse again
+    // would do nothing if the animation has the same play direction as the request; otherwise,
+    // the animation would start from where it is and change direction (i.e. Reversing <-> Running)
 
     enum class PlayState {
         NotStarted,
         Running,
+        Reversing,
         Finished,
-        Restarted,
     };
 
     BaseRenderNodeAnimator(float finalValue);
@@ -111,14 +119,15 @@
 
     virtual float getValue(RenderNode* target) const = 0;
     virtual void setValue(RenderNode* target, float value) = 0;
-    RenderNode* target() { return mTarget; }
 
     void callOnFinishedListener(AnimationContext& context);
 
     virtual void onStagingPlayStateChanged() {}
     virtual void onPlayTimeChanged(nsecs_t playTime) {}
+    virtual void onPushStaging() {}
 
     RenderNode* mTarget;
+    RenderNode* mStagingTarget;
 
     float mFinalValue;
     float mDeltaValue;
@@ -132,13 +141,28 @@
     nsecs_t mDuration;
     nsecs_t mStartDelay;
     bool mMayRunAsync;
+    // Play Time tracks the progress of animation, it should always be [0, mDuration], 0 being
+    // the beginning of the animation, will reach mDuration at the end of an animation.
+    nsecs_t mPlayTime;
 
     sp<AnimationListener> mListener;
 
 private:
+    enum class Request {
+        Start,
+        Reverse,
+        Reset,
+        Cancel,
+        End
+    };
     inline void checkMutable();
     virtual void transitionToRunning(AnimationContext& context);
     void doSetStartValue(float value);
+    bool updatePlayTime(nsecs_t playTime);
+    void resolveStagingRequest(Request request);
+
+    std::vector<Request> mStagingRequests;
+
 };
 
 class RenderPropertyAnimator : public BaseRenderNodeAnimator {
@@ -167,6 +191,7 @@
     virtual void setValue(RenderNode* target, float value) override;
     virtual void onAttached() override;
     virtual void onStagingPlayStateChanged() override;
+    virtual void onPushStaging() override;
 
 private:
     typedef bool (RenderProperties::*SetFloatProperty)(float value);
@@ -176,6 +201,8 @@
     const PropertyAccessors* mPropertyAccess;
 
     static const PropertyAccessors PROPERTY_ACCESSOR_LUT[];
+    bool mShouldSyncPropertyFields = false;
+    bool mShouldUpdateStagingProperties = false;
 };
 
 class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator {
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index cd30b18..2198fcc 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -27,9 +27,8 @@
 
 using namespace std;
 
-static void unref(BaseRenderNodeAnimator* animator) {
+static void detach(sp<BaseRenderNodeAnimator>& animator) {
     animator->detach();
-    animator->decStrong(nullptr);
 }
 
 AnimatorManager::AnimatorManager(RenderNode& parent)
@@ -38,14 +37,28 @@
 }
 
 AnimatorManager::~AnimatorManager() {
-    for_each(mNewAnimators.begin(), mNewAnimators.end(), unref);
-    for_each(mAnimators.begin(), mAnimators.end(), unref);
+    for_each(mNewAnimators.begin(), mNewAnimators.end(), detach);
+    for_each(mAnimators.begin(), mAnimators.end(), detach);
 }
 
 void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
-    animator->incStrong(nullptr);
+    RenderNode* stagingTarget = animator->stagingTarget();
+    if (stagingTarget == &mParent) {
+        return;
+    }
+    mNewAnimators.emplace_back(animator.get());
+    // If the animator is already attached to other RenderNode, remove it from that RenderNode's
+    // new animator list. This ensures one animator only ends up in one newAnimatorList during one
+    // frame, even when it's added multiple times to multiple targets.
+    if (stagingTarget) {
+        stagingTarget->removeAnimator(animator);
+    }
     animator->attach(&mParent);
-    mNewAnimators.push_back(animator.get());
+}
+
+void AnimatorManager::removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+    mNewAnimators.erase(std::remove(mNewAnimators.begin(), mNewAnimators.end(), animator),
+            mNewAnimators.end());
 }
 
 void AnimatorManager::setAnimationHandle(AnimationHandle* handle) {
@@ -56,38 +69,40 @@
             &mParent, mParent.getName());
 }
 
-template<typename T>
-static void move_all(T& source, T& dest) {
-    dest.reserve(source.size() + dest.size());
-    for (typename T::iterator it = source.begin(); it != source.end(); it++) {
-        dest.push_back(*it);
-    }
-    source.clear();
-}
-
 void AnimatorManager::pushStaging() {
     if (mNewAnimators.size()) {
         LOG_ALWAYS_FATAL_IF(!mAnimationHandle,
                 "Trying to start new animators on %p (%s) without an animation handle!",
                 &mParent, mParent.getName());
-        // Since this is a straight move, we don't need to inc/dec the ref count
-        move_all(mNewAnimators, mAnimators);
+
+        // Only add new animators that are not already in the mAnimators list
+        for (auto& anim : mNewAnimators) {
+            if (anim->target() != &mParent) {
+                mAnimators.push_back(std::move(anim));
+            }
+        }
+        mNewAnimators.clear();
     }
-    for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) {
-        (*it)->pushStaging(mAnimationHandle->context());
+    for (auto& animator : mAnimators) {
+        animator->pushStaging(mAnimationHandle->context());
     }
 }
 
+void AnimatorManager::onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) {
+    LOG_ALWAYS_FATAL_IF(animator->target() == &mParent, "Target has not been changed");
+    mAnimators.erase(std::remove(mAnimators.begin(), mAnimators.end(), animator), mAnimators.end());
+}
+
 class AnimateFunctor {
 public:
     AnimateFunctor(TreeInfo& info, AnimationContext& context)
             : dirtyMask(0), mInfo(info), mContext(context) {}
 
-    bool operator() (BaseRenderNodeAnimator* animator) {
+    bool operator() (sp<BaseRenderNodeAnimator>& animator) {
         dirtyMask |= animator->dirtyMask();
         bool remove = animator->animate(mContext);
         if (remove) {
-            animator->decStrong(nullptr);
+            animator->detach();
         } else {
             if (animator->isRunning()) {
                 mInfo.out.hasAnimations = true;
@@ -129,20 +144,18 @@
 
 uint32_t AnimatorManager::animateCommon(TreeInfo& info) {
     AnimateFunctor functor(info, mAnimationHandle->context());
-    std::vector< BaseRenderNodeAnimator* >::iterator newEnd;
-    newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
+    auto newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
     mAnimators.erase(newEnd, mAnimators.end());
     mAnimationHandle->notifyAnimationsRan();
     mParent.mProperties.updateMatrix();
     return functor.dirtyMask;
 }
 
-static void endStagingAnimator(BaseRenderNodeAnimator* animator) {
-    animator->end();
+static void endStagingAnimator(sp<BaseRenderNodeAnimator>& animator) {
+    animator->cancel();
     if (animator->listener()) {
-        animator->listener()->onAnimationFinished(animator);
+        animator->listener()->onAnimationFinished(animator.get());
     }
-    animator->decStrong(nullptr);
 }
 
 void AnimatorManager::endAllStagingAnimators() {
@@ -157,9 +170,8 @@
 public:
     EndActiveAnimatorsFunctor(AnimationContext& context) : mContext(context) {}
 
-    void operator() (BaseRenderNodeAnimator* animator) {
+    void operator() (sp<BaseRenderNodeAnimator>& animator) {
         animator->forceEndNow(mContext);
-        animator->decStrong(nullptr);
     }
 
 private:
diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h
index fb75eb8..61f6179 100644
--- a/libs/hwui/AnimatorManager.h
+++ b/libs/hwui/AnimatorManager.h
@@ -39,11 +39,13 @@
     ~AnimatorManager();
 
     void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
+    void removeAnimator(const sp<BaseRenderNodeAnimator>& animator);
 
     void setAnimationHandle(AnimationHandle* handle);
     bool hasAnimationHandle() { return mAnimationHandle; }
 
     void pushStaging();
+    void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator);
 
     // Returns the combined dirty mask of all animators run
     uint32_t animate(TreeInfo& info);
@@ -66,9 +68,8 @@
     AnimationHandle* mAnimationHandle;
 
     // To improve the efficiency of resizing & removing from the vector
-    // use manual ref counting instead of sp<>.
-    std::vector<BaseRenderNodeAnimator*> mNewAnimators;
-    std::vector<BaseRenderNodeAnimator*> mAnimators;
+    std::vector< sp<BaseRenderNodeAnimator> > mNewAnimators;
+    std::vector< sp<BaseRenderNodeAnimator> > mAnimators;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/PropertyValuesAnimatorSet.cpp b/libs/hwui/PropertyValuesAnimatorSet.cpp
index eca1afcc..b29f91f 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.cpp
+++ b/libs/hwui/PropertyValuesAnimatorSet.cpp
@@ -17,6 +17,8 @@
 #include "PropertyValuesAnimatorSet.h"
 #include "RenderNode.h"
 
+#include <algorithm>
+
 namespace android {
 namespace uirenderer {
 
@@ -53,16 +55,26 @@
 }
 
 void PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) {
-    for (size_t i = 0; i < mAnimators.size(); i++) {
-        mAnimators[i]->setCurrentPlayTime(playTime);
+    if (playTime == 0 && mDuration > 0) {
+        // Reset all the animators
+        for (auto it = mAnimators.rbegin(); it != mAnimators.rend(); it++) {
+            // Note that this set may containing animators modifying the same property, so when we
+            // reset the animators, we need to make sure the animators that end the first will
+            // have the final say on what the property value should be.
+            (*it)->setFraction(0);
+        }
+    } else if (playTime >= mDuration) {
+        // Skip all the animators to end
+        for (auto& anim : mAnimators) {
+            anim->setFraction(1);
+        }
+    } else {
+        for (auto& anim : mAnimators) {
+            anim->setCurrentPlayTime(playTime);
+        }
     }
 }
 
-void PropertyValuesAnimatorSet::reset() {
-    // TODO: implement reset through adding a play state because we need to support reset() even
-    // during an animation run.
-}
-
 void PropertyValuesAnimatorSet::start(AnimationListener* listener) {
     init();
     mOneShotListener = listener;
@@ -70,20 +82,23 @@
 }
 
 void PropertyValuesAnimatorSet::reverse(AnimationListener* listener) {
-// TODO: implement reverse
+    init();
+    mOneShotListener = listener;
+    BaseRenderNodeAnimator::reverse();
 }
 
 void PropertyValuesAnimatorSet::init() {
     if (mInitialized) {
         return;
     }
-    nsecs_t maxDuration = 0;
-    for (size_t i = 0; i < mAnimators.size(); i++) {
-        if (maxDuration < mAnimators[i]->getTotalDuration()) {
-            maxDuration = mAnimators[i]->getTotalDuration();
-        }
-    }
-    mDuration = maxDuration;
+
+    // Sort the animators by their total duration. Note that all the animators in the set start at
+    // the same time, so the ones with longer total duration (which includes start delay) will
+    // be the ones that end later.
+    std::sort(mAnimators.begin(), mAnimators.end(), [](auto& a, auto&b) {
+        return a->getTotalDuration() < b->getTotalDuration();
+    });
+    mDuration = mAnimators[mAnimators.size() - 1]->getTotalDuration();
     mInitialized = true;
 }
 
@@ -106,18 +121,19 @@
 void PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) {
     if (playTime >= mStartDelay && playTime < mTotalDuration) {
          nsecs_t currentIterationPlayTime = (playTime - mStartDelay) % mDuration;
-         mLatestFraction = currentIterationPlayTime / (float) mDuration;
+         float fraction = currentIterationPlayTime / (float) mDuration;
+         setFraction(fraction);
     } else if (mLatestFraction < 1.0f && playTime >= mTotalDuration) {
-        mLatestFraction = 1.0f;
-    } else {
-        return;
+        // This makes sure we only set the fraction = 1 once. It is needed because there might
+        // be another animator modifying the same property after this animator finishes, we need
+        // to make sure we don't set conflicting values on the same property within one frame.
+        setFraction(1.0f);
     }
-
-    setFraction(mLatestFraction);
 }
 
 void PropertyAnimator::setFraction(float fraction) {
-    float interpolatedFraction = mInterpolator->interpolate(mLatestFraction);
+    mLatestFraction = fraction;
+    float interpolatedFraction = mInterpolator->interpolate(fraction);
     mPropertyValuesHolder->setFraction(interpolatedFraction);
 }
 
diff --git a/libs/hwui/PropertyValuesAnimatorSet.h b/libs/hwui/PropertyValuesAnimatorSet.h
index 4c7ce52..c7ae7c0 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.h
+++ b/libs/hwui/PropertyValuesAnimatorSet.h
@@ -50,7 +50,6 @@
 
     void start(AnimationListener* listener);
     void reverse(AnimationListener* listener);
-    void reset();
 
     void addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
             Interpolator* interpolators, int64_t startDelays,
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 269e590..0adb21c 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -406,12 +406,16 @@
 
 void RecordingCanvas::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
-    addOp(alloc().create_trivial<ArcOp>(
-            Rect(left, top, right, bottom),
-            *(mState.currentSnapshot()->transform),
-            getRecordedClip(),
-            refPaint(&paint),
-            startAngle, sweepAngle, useCenter));
+    if (fabs(sweepAngle) >= 360.0f) {
+        drawOval(left, top, right, bottom, paint);
+    } else {
+        addOp(alloc().create_trivial<ArcOp>(
+                Rect(left, top, right, bottom),
+                *(mState.currentSnapshot()->transform),
+                getRecordedClip(),
+                refPaint(&paint),
+                startAngle, sweepAngle, useCenter));
+    }
 }
 
 void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index bade216..9ac76a4 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -218,6 +218,10 @@
     mAnimatorManager.addAnimator(animator);
 }
 
+void RenderNode::removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+    mAnimatorManager.removeAnimator(animator);
+}
+
 void RenderNode::damageSelf(TreeInfo& info) {
     if (isRenderable()) {
         if (properties().getClipDamageToBounds()) {
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index f248de54..e037645 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -187,6 +187,12 @@
 
     // UI thread only!
     ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
+    void removeAnimator(const sp<BaseRenderNodeAnimator>& animator);
+
+    // This can only happen during pushStaging()
+    void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) {
+        mAnimatorManager.onAnimatorTargetChanged(animator);
+    }
 
     AnimatorManager& animators() { return mAnimatorManager; }
 
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 3440d03..9595a85 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -162,6 +162,7 @@
 
     renderState.onGLContextCreated();
     rtCallback(renderthread::RenderThread::getInstance());
+    renderState.flush(Caches::FlushMode::Full);
     renderState.onGLContextDestroyed();
 
     // Restore the previous signal handler
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 20d2f1f..cd9ffc5 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -57,6 +57,22 @@
             << "Clip should be serialized once";
 }
 
+TEST(RecordingCanvas, drawArc) {
+    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
+        canvas.drawArc(0, 0, 200, 200, 0, 180, true, SkPaint());
+        canvas.drawArc(0, 0, 100, 100, 0, 360, true, SkPaint());
+    });
+
+    auto&& ops = dl->getOps();
+    ASSERT_EQ(2u, ops.size()) << "Must be exactly two ops";
+    EXPECT_EQ(RecordedOpId::ArcOp, ops[0]->opId);
+    EXPECT_EQ(Rect(200, 200), ops[0]->unmappedBounds);
+
+    EXPECT_EQ(RecordedOpId::OvalOp, ops[1]->opId)
+            << "Circular arcs should be converted to ovals";
+    EXPECT_EQ(Rect(100, 100), ops[1]->unmappedBounds);
+}
+
 TEST(RecordingCanvas, drawLines) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
         SkPaint paint;
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index 37ef3df79..5ba3f2c 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -73,7 +73,7 @@
     private double mBiasUncertaintyInNs;
     private double mDriftInNsPerSec;
     private double mDriftUncertaintyInNsPerSec;
-    private long mTimeOfLastHwClockDiscontinuityInNs;
+    private int mHardwareClockDiscontinuityCount;
 
     GnssClock() {
         initialize();
@@ -93,7 +93,7 @@
         mBiasUncertaintyInNs = clock.mBiasUncertaintyInNs;
         mDriftInNsPerSec = clock.mDriftInNsPerSec;
         mDriftUncertaintyInNsPerSec = clock.mDriftUncertaintyInNsPerSec;
-        mTimeOfLastHwClockDiscontinuityInNs = clock.mTimeOfLastHwClockDiscontinuityInNs;
+        mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount;
     }
 
     /**
@@ -395,17 +395,17 @@
     }
 
     /**
-     * Gets time of last hardware clock discontinuity.
+     * Gets count of last hardware clock discontinuity.
      */
-    public long getTimeOfLastHwClockDiscontinuityInNs() {
-        return mTimeOfLastHwClockDiscontinuityInNs;
+    public int getHardwareClockDiscontinuityCount() {
+        return mHardwareClockDiscontinuityCount;
     }
 
     /**
-     * Sets time of last hardware clock discontinuity.
+     * Sets count of last hardware clock discontinuity.
      */
-    public void setTimeOfLastHwClockDiscontinuityInNs(long timeOfLastHwClockDiscontinuityInNs) {
-        mTimeOfLastHwClockDiscontinuityInNs = timeOfLastHwClockDiscontinuityInNs;
+    public void setHardwareClockDiscontinuityCount(int value) {
+        mHardwareClockDiscontinuityCount = value;
     }
 
     /**
@@ -431,7 +431,7 @@
             gpsClock.mBiasUncertaintyInNs = parcel.readDouble();
             gpsClock.mDriftInNsPerSec = parcel.readDouble();
             gpsClock.mDriftUncertaintyInNsPerSec = parcel.readDouble();
-            gpsClock.mTimeOfLastHwClockDiscontinuityInNs = parcel.readLong();
+            gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt();
 
             return gpsClock;
         }
@@ -442,6 +442,7 @@
         }
     };
 
+    @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mFlags);
         parcel.writeInt(mLeapSecond);
@@ -453,7 +454,7 @@
         parcel.writeDouble(mBiasUncertaintyInNs);
         parcel.writeDouble(mDriftInNsPerSec);
         parcel.writeDouble(mDriftUncertaintyInNsPerSec);
-        parcel.writeLong(mTimeOfLastHwClockDiscontinuityInNs);
+        parcel.writeInt(mHardwareClockDiscontinuityCount);
     }
 
     @Override
@@ -497,9 +498,9 @@
                 "DriftUncertaintyInNsPerSec",
                 hasDriftUncertaintyInNsPerSec() ? mDriftUncertaintyInNsPerSec : null));
 
-        builder.append(String.format(format, "TimeOfLastHwClockDiscontinuityInNs",
+        builder.append(String.format(format, "HardwareClockDiscontinuityCount",
                 getType() == CLOCK_TYPE_LOCAL_HW_TIME
-                        ? mTimeOfLastHwClockDiscontinuityInNs : null));
+                        ? mHardwareClockDiscontinuityCount : null));
 
         return builder.toString();
     }
@@ -515,7 +516,7 @@
         resetBiasUncertaintyInNs();
         resetDriftInNsPerSec();
         resetDriftUncertaintyInNsPerSec();
-        setTimeOfLastHwClockDiscontinuityInNs(Long.MIN_VALUE);
+        setHardwareClockDiscontinuityCount(Integer.MIN_VALUE);
     }
 
     private void setFlag(short flag) {
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index a490685..a619ab2 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -24,15 +24,16 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * A class representing a GPS satellite measurement, containing raw and computed information.
+ * A class representing a GNSS satellite measurement, containing raw and computed information.
  */
 public final class GnssMeasurement implements Parcelable {
     private int mFlags;
     private short mSvid;
+    private byte mConstellationType;
     private double mTimeOffsetInNs;
     private short mState;
-    private long mReceivedGpsTowInNs;
-    private long mReceivedGpsTowUncertaintyInNs;
+    private long mReceivedSvTimeInNs;
+    private long mReceivedSvTimeUncertaintyInNs;
     private double mCn0InDbHz;
     private double mPseudorangeRateInMetersPerSec;
     private double mPseudorangeRateUncertaintyInMetersPerSec;
@@ -59,8 +60,6 @@
     private double mAzimuthInDeg;
     private double mAzimuthUncertaintyInDeg;
     private boolean mUsedInFix;
-    private double mPseudorangeRateCarrierInMetersPerSec;
-    private double mPseudorangeRateCarrierUncertaintyInMetersPerSec;
 
     // The following enumerations must be in sync with the values declared in gps.h
 
@@ -82,8 +81,8 @@
     private static final int HAS_TIME_FROM_LAST_BIT = (1<<14);
     private static final int HAS_DOPPLER_SHIFT = (1<<15);
     private static final int HAS_DOPPLER_SHIFT_UNCERTAINTY = (1<<16);
-    private static final int HAS_USED_IN_FIX = (1<<17);
-    private static final int GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18);
+    // private static final int HAS_USED_IN_FIX = (1<<17);
+    private static final int HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18);
 
     /** The status of 'loss of lock'. */
     @Retention(RetentionPolicy.SOURCE)
@@ -127,37 +126,37 @@
     public static final byte MULTIPATH_INDICATOR_NOT_USED = 2;
 
     /**
-     * The state of GPS receiver the measurement is invalid or unknown.
+     * The state of GNSS receiver the measurement is invalid or unknown.
      */
     public static final short STATE_UNKNOWN = 0;
 
     /**
-     * The state of the GPS receiver is ranging code lock.
+     * The state of the GNSS receiver is ranging code lock.
      */
     public static final short STATE_CODE_LOCK = (1<<0);
 
     /**
-     * The state of the GPS receiver is in bit sync.
+     * The state of the GNSS receiver is in bit sync.
      */
     public static final short STATE_BIT_SYNC = (1<<1);
 
     /**
-     *The state of the GPS receiver is in sub-frame sync.
+     *The state of the GNSS receiver is in sub-frame sync.
      */
     public static final short STATE_SUBFRAME_SYNC = (1<<2);
 
     /**
-     * The state of the GPS receiver has TOW decoded.
+     * The state of the GNSS receiver has TOW decoded.
      */
     public static final short STATE_TOW_DECODED = (1<<3);
 
     /**
-     * The state of the GPS receiver contains millisecond ambiguity.
+     * The state of the GNSS receiver contains millisecond ambiguity.
      */
     public static final short STATE_MSEC_AMBIGUOUS = (1<<4);
 
     /**
-     * All the GPS receiver state flags.
+     * All the GNSS receiver state flags.
      */
     private static final short STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
             | STATE_TOW_DECODED | STATE_MSEC_AMBIGUOUS;
@@ -199,10 +198,11 @@
     public void set(GnssMeasurement measurement) {
         mFlags = measurement.mFlags;
         mSvid = measurement.mSvid;
+        mConstellationType = measurement.mConstellationType;
         mTimeOffsetInNs = measurement.mTimeOffsetInNs;
         mState = measurement.mState;
-        mReceivedGpsTowInNs = measurement.mReceivedGpsTowInNs;
-        mReceivedGpsTowUncertaintyInNs = measurement.mReceivedGpsTowUncertaintyInNs;
+        mReceivedSvTimeInNs = measurement.mReceivedSvTimeInNs;
+        mReceivedSvTimeUncertaintyInNs = measurement.mReceivedSvTimeUncertaintyInNs;
         mCn0InDbHz = measurement.mCn0InDbHz;
         mPseudorangeRateInMetersPerSec = measurement.mPseudorangeRateInMetersPerSec;
         mPseudorangeRateUncertaintyInMetersPerSec =
@@ -231,10 +231,6 @@
         mAzimuthInDeg = measurement.mAzimuthInDeg;
         mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg;
         mUsedInFix = measurement.mUsedInFix;
-        mPseudorangeRateCarrierInMetersPerSec =
-                measurement.mPseudorangeRateCarrierInMetersPerSec;
-        mPseudorangeRateCarrierUncertaintyInMetersPerSec =
-                measurement.mPseudorangeRateCarrierUncertaintyInMetersPerSec;
     }
 
     /**
@@ -260,6 +256,21 @@
     }
 
     /**
+     * Getst the constellation type.
+     */
+    @GnssStatus.ConstellationType
+    public byte getConstellationType() {
+        return mConstellationType;
+    }
+
+    /**
+     * Sets the constellation type.
+     */
+    public void setConstellationType(@GnssStatus.ConstellationType byte value) {
+        mConstellationType = value;
+    }
+
+    /**
      * Gets the time offset at which the measurement was taken in nanoseconds.
      * The reference receiver's time is specified by {@link GnssClock#getTimeInNs()} and should be
      * interpreted in the same way as indicated by {@link GnssClock#getType()}.
@@ -285,7 +296,7 @@
      * Gets per-satellite sync state.
      * It represents the current sync state for the associated satellite.
      *
-     * This value helps interpret {@link #getReceivedGpsTowInNs()}.
+     * This value helps interpret {@link #getReceivedSvTimeInNs()}.
      */
     public short getState() {
         return mState;
@@ -333,39 +344,92 @@
     }
 
     /**
-     * Gets the received GPS Time-of-Week at the measurement time, in nanoseconds.
-     * The value is relative to the beginning of the current GPS week.
+     * Gets the received GNSS satellite time, at the measurement time, in nanoseconds.
      *
-     * Given {@link #getState()} of the GPS receiver, the range of this field can be:
-     *      Searching           : [ 0           ]   : {@link #STATE_UNKNOWN} is set
-     *      Ranging code lock   : [ 0    1 ms   ]   : {@link #STATE_CODE_LOCK} is set
-     *      Bit sync            : [ 0   20 ms   ]   : {@link #STATE_BIT_SYNC} is set
-     *      Subframe sync       : [ 0    6 ms   ]   : {@link #STATE_SUBFRAME_SYNC} is set
-     *      TOW decoded         : [ 0    1 week ]   : {@link #STATE_TOW_DECODED} is set
+     * 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.
+     *
+     *   Given the highest sync state that can be achieved, per each satellite, valid range
+     *   for this field can be:
+     *     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
+     *
+     *   Note well: if there is any ambiguity in integer millisecond,
+     *   STATE_MSEC_AMBIGUOUS should be set accordingly, in the 'state' field.
+     *
+     *   This value must be populated if 'state' != STATE_UNKNOWN.
+     *
+     * For Glonass, this is:
+     *   Received Glonass time of day, 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:
+     *     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
+     *
+     * For Beidou, this is:
+     *   Received Beidou time of week, 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:
+     *     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
+     *
+     * For Galileo, this is:
+     *   Received Galileo time of week, at the measurement time in nanoseconds.
+     *
+     *     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
+     *
+     *   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:
+     *     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
      */
-    public long getReceivedGpsTowInNs() {
-        return mReceivedGpsTowInNs;
+    public long getReceivedSvTimeInNs() {
+        return mReceivedSvTimeInNs;
     }
 
     /**
-     * Sets the received GPS time-of-week in nanoseconds.
+     * Sets the received GNSS time in nanoseconds.
      */
-    public void setReceivedGpsTowInNs(long value) {
-        mReceivedGpsTowInNs = value;
+    public void setReceivedSvTimeInNs(long value) {
+        mReceivedSvTimeInNs = value;
     }
 
     /**
-     * Gets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
+     * Gets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
      */
-    public long getReceivedGpsTowUncertaintyInNs() {
-        return mReceivedGpsTowUncertaintyInNs;
+    public long getReceivedSvTimeUncertaintyInNs() {
+        return mReceivedSvTimeUncertaintyInNs;
     }
 
     /**
-     * Sets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
+     * Sets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
      */
-    public void setReceivedGpsTowUncertaintyInNs(long value) {
-        mReceivedGpsTowUncertaintyInNs = value;
+    public void setReceivedSvTimeUncertaintyInNs(long value) {
+        mReceivedSvTimeUncertaintyInNs = value;
     }
 
     /**
@@ -416,7 +480,7 @@
      *         value, {@code false} if it contains an uncorrected value.
      */
     public boolean isPseudorangeRateCorrected() {
-        return !isFlagSet(GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE);
+        return !isFlagSet(HAS_UNCORRECTED_PSEUDORANGE_RATE);
     }
 
     /**
@@ -1160,7 +1224,7 @@
     }
 
     /**
-     * Gets a flag indicating whether the GPS represented by the measurement was used for computing
+     * Gets a flag indicating whether the GNSS represented by the measurement was used for computing
      * the most recent fix.
      *
      * @return A non-null value if the data is available, null otherwise.
@@ -1176,34 +1240,6 @@
         mUsedInFix = value;
     }
 
-    /**
-     * Gets pseudorange rate (based on carrier phase changes) at the timestamp in m/s.
-     */
-    public double getPseudorangeRateCarrierInMetersPerSec() {
-        return mPseudorangeRateCarrierInMetersPerSec;
-    }
-
-    /**
-     * Sets pseudorange rate (based on carrier phase changes) at the timestamp in m/s.
-     */
-    public void setPseudorangeRateCarrierInMetersPerSec(double value) {
-        mPseudorangeRateCarrierInMetersPerSec = value;
-    }
-
-    /**
-     * Gets 1-Sigma uncertainty of the pseudorange rate carrier.
-     */
-    public double getPseudorangeRateCarrierUncertaintyInMetersPerSec() {
-        return mPseudorangeRateCarrierUncertaintyInMetersPerSec;
-    }
-
-    /**
-     * Sets 1-Sigma uncertainty of the pseudorange rate carrier.
-     */
-    public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double value) {
-        mPseudorangeRateCarrierUncertaintyInMetersPerSec = value;
-    }
-
     public static final Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
         @Override
         public GnssMeasurement createFromParcel(Parcel parcel) {
@@ -1211,10 +1247,11 @@
 
             gnssMeasurement.mFlags = parcel.readInt();
             gnssMeasurement.mSvid = (short) parcel.readInt();
+            gnssMeasurement.mConstellationType = parcel.readByte();
             gnssMeasurement.mTimeOffsetInNs = parcel.readDouble();
             gnssMeasurement.mState = (short) parcel.readInt();
-            gnssMeasurement.mReceivedGpsTowInNs = parcel.readLong();
-            gnssMeasurement.mReceivedGpsTowUncertaintyInNs = parcel.readLong();
+            gnssMeasurement.mReceivedSvTimeInNs = parcel.readLong();
+            gnssMeasurement.mReceivedSvTimeUncertaintyInNs = parcel.readLong();
             gnssMeasurement.mCn0InDbHz = parcel.readDouble();
             gnssMeasurement.mPseudorangeRateInMetersPerSec = parcel.readDouble();
             gnssMeasurement.mPseudorangeRateUncertaintyInMetersPerSec = parcel.readDouble();
@@ -1241,8 +1278,6 @@
             gnssMeasurement.mAzimuthInDeg = parcel.readDouble();
             gnssMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble();
             gnssMeasurement.mUsedInFix = parcel.readInt() != 0;
-            gnssMeasurement.mPseudorangeRateCarrierInMetersPerSec = parcel.readDouble();
-            gnssMeasurement.mPseudorangeRateCarrierUncertaintyInMetersPerSec = parcel.readDouble();
 
             return gnssMeasurement;
         }
@@ -1257,10 +1292,11 @@
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mFlags);
         parcel.writeInt(mSvid);
+        parcel.writeByte(mConstellationType);
         parcel.writeDouble(mTimeOffsetInNs);
         parcel.writeInt(mState);
-        parcel.writeLong(mReceivedGpsTowInNs);
-        parcel.writeLong(mReceivedGpsTowUncertaintyInNs);
+        parcel.writeLong(mReceivedSvTimeInNs);
+        parcel.writeLong(mReceivedSvTimeUncertaintyInNs);
         parcel.writeDouble(mCn0InDbHz);
         parcel.writeDouble(mPseudorangeRateInMetersPerSec);
         parcel.writeDouble(mPseudorangeRateUncertaintyInMetersPerSec);
@@ -1287,8 +1323,6 @@
         parcel.writeDouble(mAzimuthInDeg);
         parcel.writeDouble(mAzimuthUncertaintyInDeg);
         parcel.writeInt(mUsedInFix ? 1 : 0);
-        parcel.writeDouble(mPseudorangeRateCarrierInMetersPerSec);
-        parcel.writeDouble(mPseudorangeRateCarrierUncertaintyInMetersPerSec);
     }
 
     @Override
@@ -1303,17 +1337,17 @@
         StringBuilder builder = new StringBuilder("GnssMeasurement:\n");
 
         builder.append(String.format(format, "Svid", mSvid));
-
+        builder.append(String.format(format, "ConstellationType", mConstellationType));
         builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
 
         builder.append(String.format(format, "State", getStateString()));
 
         builder.append(String.format(
                 formatWithUncertainty,
-                "ReceivedGpsTowInNs",
-                mReceivedGpsTowInNs,
-                "ReceivedGpsTowUncertaintyInNs",
-                mReceivedGpsTowUncertaintyInNs));
+                "ReceivedSvTimeInNs",
+                mReceivedSvTimeInNs,
+                "ReceivedSvTimeUncertaintyInNs",
+                mReceivedSvTimeUncertaintyInNs));
 
         builder.append(String.format(format, "Cn0InDbHz", mCn0InDbHz));
 
@@ -1413,11 +1447,6 @@
 
         builder.append(String.format(format, "UsedInFix", mUsedInFix));
 
-        builder.append(String.format(format, "PseudorangeRateCarrierInMetersPerSec",
-                    mPseudorangeRateCarrierInMetersPerSec));
-        builder.append(String.format(format, "PseudorangeRateCarrierUncertaintyInMetersPerSec",
-                    mPseudorangeRateCarrierUncertaintyInMetersPerSec));
-
         return builder.toString();
     }
 
@@ -1426,8 +1455,8 @@
         setSvid((short) 0);
         setTimeOffsetInNs(Long.MIN_VALUE);
         setState(STATE_UNKNOWN);
-        setReceivedGpsTowInNs(Long.MIN_VALUE);
-        setReceivedGpsTowUncertaintyInNs(Long.MAX_VALUE);
+        setReceivedSvTimeInNs(Long.MIN_VALUE);
+        setReceivedSvTimeUncertaintyInNs(Long.MAX_VALUE);
         setCn0InDbHz(Double.MIN_VALUE);
         setPseudorangeRateInMetersPerSec(Double.MIN_VALUE);
         setPseudorangeRateUncertaintyInMetersPerSec(Double.MIN_VALUE);
@@ -1454,8 +1483,6 @@
         resetAzimuthInDeg();
         resetAzimuthUncertaintyInDeg();
         setUsedInFix(false);
-        setPseudorangeRateCarrierInMetersPerSec(Double.MIN_VALUE);
-        setPseudorangeRateCarrierUncertaintyInMetersPerSec(Double.MIN_VALUE);
     }
 
     private void setFlag(int flag) {
diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java
index 86328eb..faefd0bb 100644
--- a/location/java/android/location/GnssNavigationMessage.java
+++ b/location/java/android/location/GnssNavigationMessage.java
@@ -34,36 +34,33 @@
 
     /** The type of the GPS Clock. */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({MESSAGE_TYPE_UNKNOWN, MESSAGE_TYPE_L1CA, MESSAGE_TYPE_L2CNAV, MESSAGE_TYPE_L5CNAV,
-            MESSAGE_TYPE_CNAV2})
+    @IntDef({MESSAGE_TYPE_UNKNOWN, MESSAGE_TYPE_GPS_L1CA, MESSAGE_TYPE_GPS_L2CNAV,
+        MESSAGE_TYPE_GPS_L5CNAV, MESSAGE_TYPE_GPS_CNAV2, MESSAGE_TYPE_GLO_L1CA, MESSAGE_TYPE_BDS_D1,
+        MESSAGE_TYPE_BDS_D2, MESSAGE_TYPE_GAL_I, MESSAGE_TYPE_GAL_F})
     public @interface GnssNavigationMessageType {}
 
     // The following enumerations must be in sync with the values declared in gps.h
 
-    /**
-     * The type of the navigation message is not available or unknown.
-     */
-    public static final byte MESSAGE_TYPE_UNKNOWN = 0;
-
-    /**
-     * The Navigation Message is of type L1 C/A.
-     */
-    public static final byte MESSAGE_TYPE_L1CA = 1;
-
-    /**
-     * The Navigation Message is of type L1-CNAV.
-     */
-    public static final byte MESSAGE_TYPE_L2CNAV = 2;
-
-    /**
-     * The Navigation Message is of type L5-CNAV.
-     */
-    public static final byte MESSAGE_TYPE_L5CNAV = 3;
-
-    /**
-     * The Navigation Message is of type CNAV-2.
-     */
-    public static final byte MESSAGE_TYPE_CNAV2 = 4;
+    /** Message type unknown */
+    public static final short MESSAGE_TYPE_UNKNOWN = 0;
+    /** GPS L1 C/A message contained in the structure.  */
+    public static final short MESSAGE_TYPE_GPS_L1CA = 0x0101;
+    /** GPS L2-CNAV message contained in the structure. */
+    public static final short MESSAGE_TYPE_GPS_L2CNAV = 0x0102;
+    /** GPS L5-CNAV message contained in the structure. */
+    public static final short MESSAGE_TYPE_GPS_L5CNAV = 0x0103;
+    /** GPS CNAV-2 message contained in the structure. */
+    public static final short MESSAGE_TYPE_GPS_CNAV2 = 0x0104;
+    /** Glonass L1 CA message contained in the structure. */
+    public static final short MESSAGE_TYPE_GLO_L1CA = 0x0301;
+    /** Beidou D1 message contained in the structure. */
+    public static final short MESSAGE_TYPE_BDS_D1 = 0x0501;
+    /** Beidou D2 message contained in the structure. */
+    public static final short MESSAGE_TYPE_BDS_D2 = 0x0502;
+    /** Galileo I/NAV message contained in the structure. */
+    public static final short MESSAGE_TYPE_GAL_I = 0x0601;
+    /** Galileo F/NAV message contained in the structure. */
+    public static final short MESSAGE_TYPE_GAL_F = 0x0602;
 
     /**
      * The Navigation Message Status is 'unknown'.
@@ -83,7 +80,7 @@
 
     // End enumerations in sync with gps.h
 
-    private byte mType;
+    private short mType;
     private short mSvid;
     private short mMessageId;
     private short mSubmessageId;
@@ -117,14 +114,14 @@
      * Gets the type of the navigation message contained in the object.
      */
     @GnssNavigationMessageType
-    public byte getType() {
+    public short getType() {
         return mType;
     }
 
     /**
      * Sets the type of the navigation message.
      */
-    public void setType(@GnssNavigationMessageType byte value) {
+    public void setType(@GnssNavigationMessageType short value) {
         mType = value;
     }
 
@@ -136,14 +133,24 @@
         switch (mType) {
             case MESSAGE_TYPE_UNKNOWN:
                 return "Unknown";
-            case MESSAGE_TYPE_L1CA:
-                return "L1 C/A";
-            case MESSAGE_TYPE_L2CNAV:
-                return "L2-CNAV";
-            case MESSAGE_TYPE_L5CNAV:
-                return "L5-CNAV";
-            case MESSAGE_TYPE_CNAV2:
-                return "CNAV-2";
+            case MESSAGE_TYPE_GPS_L1CA:
+                return "GPS L1 C/A";
+            case MESSAGE_TYPE_GPS_L2CNAV:
+                return "GPS L2-CNAV";
+            case MESSAGE_TYPE_GPS_L5CNAV:
+                return "GPS L5-CNAV";
+            case MESSAGE_TYPE_GPS_CNAV2:
+                return "GPS CNAV2";
+            case MESSAGE_TYPE_GLO_L1CA:
+                return "Glonass L1 C/A";
+            case MESSAGE_TYPE_BDS_D1:
+                return "Beidou D1";
+            case MESSAGE_TYPE_BDS_D2:
+                return "Beidou D2";
+            case MESSAGE_TYPE_GAL_I:
+                return "Galileo I";
+            case MESSAGE_TYPE_GAL_F:
+                return "Galileo F";
             default:
                 return "<Invalid:" + mType + ">";
         }
@@ -255,7 +262,7 @@
         public GnssNavigationMessage createFromParcel(Parcel parcel) {
             GnssNavigationMessage navigationMessage = new GnssNavigationMessage();
 
-            navigationMessage.setType(parcel.readByte());
+            navigationMessage.setType((short) parcel.readInt());
             navigationMessage.setSvid((short) parcel.readInt());
             navigationMessage.setMessageId((short) parcel.readInt());
             navigationMessage.setSubmessageId((short) parcel.readInt());
@@ -283,7 +290,7 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeByte(mType);
+        parcel.writeInt(mType);
         parcel.writeInt(mSvid);
         parcel.writeInt(mMessageId);
         parcel.writeInt(mSubmessageId);
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index 906e944..06ce30c 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -16,25 +16,36 @@
 
 package android.location;
 
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * This class represents the current state of the GNSS engine.
  * This class is used in conjunction with the {@link GnssStatusCallback}.
  */
 public final class GnssStatus {
     /** Unknown constellation type. */
-    public static final int CONSTELLATION_UNKNOWN = 0;
+    public static final byte CONSTELLATION_UNKNOWN = 0;
     /** Constellation type constant for GPS. */
-    public static final int CONSTELLATION_GPS = 1;
+    public static final byte CONSTELLATION_GPS = 1;
     /** Constellation type constant for SBAS. */
-    public static final int CONSTELLATION_SBAS = 2;
+    public static final byte CONSTELLATION_SBAS = 2;
     /** Constellation type constant for Glonass. */
-    public static final int CONSTELLATION_GLONASS = 3;
+    public static final byte CONSTELLATION_GLONASS = 3;
     /** Constellation type constant for QZSS. */
-    public static final int CONSTELLATION_QZSS = 4;
+    public static final byte CONSTELLATION_QZSS = 4;
     /** Constellation type constant for Beidou. */
-    public static final int CONSTELLATION_BEIDOU = 5;
+    public static final byte CONSTELLATION_BEIDOU = 5;
     /** Constellation type constant for Galileo. */
-    public static final int CONSTELLATION_GALILEO = 6;
+    public static final byte CONSTELLATION_GALILEO = 6;
+
+    /** Constellation type. */
+    @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 */
@@ -80,9 +91,10 @@
      * Retrieves the constellation type of the satellite at the specified position.
      * @param satIndex the index of the satellite in the list.
      */
-    public int getConstellationType(int satIndex) {
-        return (mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
-                & CONSTELLATION_TYPE_MASK;
+    @ConstellationType
+    public byte getConstellationType(int satIndex) {
+        return (byte) ((mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
+                & CONSTELLATION_TYPE_MASK);
     }
 
     /**
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index e41e20c..7b3dd7d 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -147,7 +147,6 @@
                     & GnssStatus.CONSTELLATION_TYPE_MASK;
             // Skip all non-GPS satellites.
             if (constellationType != GnssStatus.CONSTELLATION_GPS) {
-                // TODO: translate the defacto pre-N use of  prn's >32 to new struct
                 continue;
             }
             int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH;
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 4f1e039..bc8b026 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -69,7 +69,7 @@
             in String packageName);
     void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener);
 
-    int getGpsYearOfHardware();
+    int getGnssYearOfHardware();
 
     // --- deprecated ---
     List<String> getAllProviders();
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 23f0710..e14e36d 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1959,11 +1959,11 @@
      * @hide
      */
     @TestApi
-    public int getGpsYearOfHardware() {
+    public int getGnssYearOfHardware() {
         try {
-            return mService.getGpsYearOfHardware();
+            return mService.getGnssYearOfHardware();
         } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException in getGpsSystemInfo: ", e);
+            Log.e(TAG, "RemoteException in getGnssSystemInfo: ", e);
             return 0;
         }
     }
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index d06da97..646ab4e 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -65,6 +65,7 @@
  * <tr><th>Name</th><th>Value Type</th><th>Description</th></tr>
  * <tr><td>{@link #KEY_CHANNEL_COUNT}</td><td>Integer</td><td></td></tr>
  * <tr><td>{@link #KEY_SAMPLE_RATE}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_PCM_ENCODING}</td><td>Integer</td><td>optional</td></tr>
  * <tr><td>{@link #KEY_IS_ADTS}</td><td>Integer</td><td>optional, if <em>decoding</em> AAC audio content, setting this key to 1 indicates that each audio frame is prefixed by the ADTS header.</td></tr>
  * <tr><td>{@link #KEY_AAC_PROFILE}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is AAC audio, specifies the desired profile.</td></tr>
  * <tr><td>{@link #KEY_AAC_SBR_MODE}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is AAC audio, specifies the desired SBR mode.</td></tr>
@@ -197,6 +198,26 @@
     public static final String KEY_FRAME_RATE = "frame-rate";
 
     /**
+     * A key describing the raw audio sample encoding/format.
+     *
+     * <p>The associated value is an integer, using one of the
+     * {@link AudioFormat}.ENCODING_PCM_ values.</p>
+     *
+     * <p>This is an optional key for audio decoders and encoders specifying the
+     * desired raw audio sample format during {@link MediaCodec#configure
+     * MediaCodec.configure(&hellip;)} call. Use {@link MediaCodec#getInputFormat
+     * MediaCodec.getInput}/{@link MediaCodec#getOutputFormat OutputFormat(&hellip;)}
+     * to confirm the actual format. For the PCM decoder this key specifies both
+     * input and output sample encodings.</p>
+     *
+     * <p>This key is also used by {@link MediaExtractor} to specify the sample
+     * format of audio data, if it is specified.</p>
+     *
+     * <p>If this key is missing, the raw audio sample format is signed 16-bit short.</p>
+     */
+    public static final String KEY_PCM_ENCODING = "pcm-encoding";
+
+    /**
      * A key describing the capture rate of a video format in frames/sec.
      * <p>
      * When capture rate is different than the frame rate, it means that the
@@ -564,7 +585,7 @@
     public static final String KEY_IS_TIMED_TEXT = "is-timed-text";
 
     // The following color aspect values must be in sync with the ones in HardwareAPI.h.
-    /*
+    /**
      * An optional key describing the color primaries, white point and
      * luminance factors for video content.
      *
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index adb6b06..893bd3c 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -29,6 +29,10 @@
     void onMediaButton(in Intent mediaButtonIntent, int sequenceNumber, in ResultReceiver cb);
 
     // These callbacks are for the TransportPerformer
+    void onPrepare();
+    void onPrepareFromMediaId(String mediaId, in Bundle extras);
+    void onPrepareFromSearch(String query, in Bundle extras);
+    void onPrepareFromUri(in Uri uri, in Bundle extras);
     void onPlay();
     void onPlayFromMediaId(String mediaId, in Bundle extras);
     void onPlayFromSearch(String query, in Bundle extras);
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 285e5f7..249bcdc 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -50,6 +50,10 @@
     void setVolumeTo(int value, int flags, String packageName);
 
     // These commands are for the TransportControls
+    void prepare();
+    void prepareFromMediaId(String mediaId, in Bundle extras);
+    void prepareFromSearch(String string, in Bundle extras);
+    void prepareFromUri(in Uri uri, in Bundle extras);
     void play();
     void playFromMediaId(String mediaId, in Bundle extras);
     void playFromSearch(String string, in Bundle extras);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 3d9b60d..13db00e 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -592,6 +592,90 @@
         }
 
         /**
+         * Request that the player prepare its playback. Once the preparation is done, the session
+         * will change its playback state to {@link PlaybackState#STATE_PAUSED}. Afterwards,
+         * {@link #play} can be called to start playback. If the preparation is not needed,
+         * {@link #play} can be directly called without this method.
+         */
+        public void prepare() {
+            try {
+                mSessionBinder.prepare();
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare.", e);
+            }
+        }
+
+        /**
+         * Request that the player prepare playback for a specific media id. Once the preparation is
+         * done, the session will change its playback state to {@link PlaybackState#STATE_PAUSED}.
+         * Afterwards, {@link #play} can be called to start playback. If the preparation is not
+         * needed, {@link #playFromMediaId} can be directly called without this method.
+         *
+         * @param mediaId The id of the requested media.
+         * @param extras Optional extras that can include extra information about the media item
+         *               to be prepared.
+         */
+        public void prepareFromMediaId(String mediaId, Bundle extras) {
+            if (TextUtils.isEmpty(mediaId)) {
+                throw new IllegalArgumentException(
+                        "You must specify a non-empty String for prepareFromMediaId.");
+            }
+            try {
+                mSessionBinder.prepareFromMediaId(mediaId, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player prepare playback for a specific search query.
+         * An empty or null query should be treated as a request to prepare any
+         * music. Once the preparation is done, the session will change its playback state to
+         * {@link PlaybackState#STATE_PAUSED}. Afterwards, {@link #play} can be called to start
+         * playback. If the preparation is not needed, {@link #playFromSearch} can be directly
+         * called without this method.
+         *
+         * @param query The search query.
+         * @param extras Optional extras that can include extra information
+         *               about the query.
+         */
+        public void prepareFromSearch(String query, Bundle extras) {
+            if (query == null) {
+                // This is to remain compatible with
+                // INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
+                query = "";
+            }
+            try {
+                mSessionBinder.prepareFromSearch(query, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player prepare playback for a specific {@link Uri}.
+         * Once the preparation is done, the session will change its playback state to
+         * {@link PlaybackState#STATE_PAUSED}. Afterwards, {@link #play} can be called to start
+         * playback. If the preparation is not needed, {@link #playFromUri} can be directly
+         * called without this method.
+         *
+         * @param uri The URI of the requested media.
+         * @param extras Optional extras that can include extra information about the media item
+         *               to be prepared.
+         */
+        public void prepareFromUri(Uri uri, Bundle extras) {
+            if (uri == null || Uri.EMPTY.equals(uri)) {
+                throw new IllegalArgumentException(
+                        "You must specify a non-empty Uri for prepareFromUri.");
+            }
+            try {
+                mSessionBinder.prepareFromUri(uri, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
+            }
+        }
+
+        /**
          * Request that the player start its playback at its current position.
          */
         public void play() {
@@ -605,7 +689,6 @@
         /**
          * Request that the player start playback for a specific media id.
          *
-         * @see PlaybackState#EXTRA_PREPARE_ONLY
          * @param mediaId The id of the requested media.
          * @param extras Optional extras that can include extra information about the media item
          *               to be played.
@@ -627,10 +710,9 @@
          * An empty or null query should be treated as a request to play any
          * music.
          *
-         * @see PlaybackState#EXTRA_PREPARE_ONLY
          * @param query The search query.
          * @param extras Optional extras that can include extra information
-         *            about the query.
+         *               about the query.
          */
         public void playFromSearch(String query, Bundle extras) {
             if (query == null) {
@@ -648,8 +730,7 @@
         /**
          * Request that the player start playback for a specific {@link Uri}.
          *
-         * @see PlaybackState#EXTRA_PREPARE_ONLY
-         * @param uri  The URI of the requested media.
+         * @param uri The URI of the requested media.
          * @param extras Optional extras that can include extra information about the media item
          *               to be played.
          */
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 8c5b19c..3b1b6c8 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -87,12 +87,6 @@
     public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1;
 
     /**
-     * Set this flag on the session to indicate that it can handle
-     * the {@link PlaybackState#EXTRA_PREPARE_ONLY} field.
-     */
-    public static final int FLAG_HANDLES_PREPARE_ONLY = 1 << 2;
-
-    /**
      * System only flag for a session that needs to have priority over all other
      * sessions. This flag ensures this session will receive media button events
      * regardless of the current ordering in the system.
@@ -106,7 +100,6 @@
     @IntDef(flag = true, value = {
             FLAG_HANDLES_MEDIA_BUTTONS,
             FLAG_HANDLES_TRANSPORT_CONTROLS,
-            FLAG_HANDLES_PREPARE_ONLY,
             FLAG_EXCLUSIVE_GLOBAL_PRIORITY })
     public @interface SessionFlags { }
 
@@ -519,6 +512,22 @@
         }
     }
 
+    private void dispatchPrepare() {
+        postToCallback(CallbackMessageHandler.MSG_PREPARE);
+    }
+
+    private void dispatchPrepareFromMediaId(String mediaId, Bundle extras) {
+        postToCallback(CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras);
+    }
+
+    private void dispatchPrepareFromSearch(String query, Bundle extras) {
+        postToCallback(CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras);
+    }
+
+    private void dispatchPrepareFromUri(Uri uri, Bundle extras) {
+        postToCallback(CallbackMessageHandler.MSG_PREPARE_URI, uri, extras);
+    }
+
     private void dispatchPlay() {
         postToCallback(CallbackMessageHandler.MSG_PLAY);
     }
@@ -805,16 +814,49 @@
         }
 
         /**
-         * Override to handle requests to begin playback.
+         * Override to handle requests to prepare playback. The state of playback should be updated
+         * to {@link PlaybackState#STATE_PAUSED} after the preparation is done. Override
+         * {@link #onPlay} to handle requests for starting playback of prepared content.
          */
-        public void onPlay() {
+        public void onPrepare() {
         }
 
         /**
-         * Override to handle requests to play a specific mediaId that was
-         * provided by your app's {@link MediaBrowserService}.
+         * Override to handle requests to prepare for playing a specific mediaId that was provided
+         * by your app's {@link MediaBrowserService}. The state of playback should be updated
+         * to {@link PlaybackState#STATE_PAUSED} after the preparation is done. The playback of
+         * the prepared content should start in the implementation of {@link #onPlay}. Override
+         * {@link #onPlayFromMediaId} to handle requests for starting playback without preparation.
          */
-        public void onPlayFromMediaId(String mediaId, Bundle extras) {
+        public void onPrepareFromMediaId(String mediaId, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to prepare playback from a search query. An
+         * empty query indicates that the app may prepare any music. The
+         * implementation should attempt to make a smart choice about what to
+         * play. The state of playback should be updated to {@link PlaybackState#STATE_PAUSED}
+         * after the preparation is done. The playback of the prepared content should start
+         * in the implementation of {@link #onPlay}. Override {@link #onPlayFromSearch}
+         * to handle requests for starting playback without preparation.
+         */
+        public void onPrepareFromSearch(String query, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to prepare a specific media item represented by a URI.
+         * The state of playback should be updated to {@link PlaybackState#STATE_PAUSED}
+         * after the preparation is done. The playback of the prepared content should start in
+         * the implementation of {@link #onPlay}. Override {@link #onPlayFromUri} to handle requests
+         * for starting playback without preparation.
+         */
+        public void onPrepareFromUri(Uri uri, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to begin playback.
+         */
+        public void onPlay() {
         }
 
         /**
@@ -827,6 +869,13 @@
         }
 
         /**
+         * Override to handle requests to play a specific mediaId that was
+         * provided by your app's {@link MediaBrowserService}.
+         */
+        public void onPlayFromMediaId(String mediaId, Bundle extras) {
+        }
+
+        /**
          * Override to handle requests to play a specific media item represented by a URI.
          */
         public void onPlayFromUri(Uri uri, Bundle extras) {
@@ -937,6 +986,38 @@
         }
 
         @Override
+        public void onPrepare() {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepare();
+            }
+        }
+
+        @Override
+        public void onPrepareFromMediaId(String mediaId, Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepareFromMediaId(mediaId, extras);
+            }
+        }
+
+        @Override
+        public void onPrepareFromSearch(String query, Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepareFromSearch(query, extras);
+            }
+        }
+
+        @Override
+        public void onPrepareFromUri(Uri uri, Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepareFromUri(uri, extras);
+            }
+        }
+
+        @Override
         public void onPlay() {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1162,24 +1243,28 @@
 
     private class CallbackMessageHandler extends Handler {
 
-        private static final int MSG_PLAY = 1;
-        private static final int MSG_PLAY_MEDIA_ID = 2;
-        private static final int MSG_PLAY_SEARCH = 3;
-        private static final int MSG_SKIP_TO_ITEM = 4;
-        private static final int MSG_PAUSE = 5;
-        private static final int MSG_STOP = 6;
-        private static final int MSG_NEXT = 7;
-        private static final int MSG_PREVIOUS = 8;
-        private static final int MSG_FAST_FORWARD = 9;
-        private static final int MSG_REWIND = 10;
-        private static final int MSG_SEEK_TO = 11;
-        private static final int MSG_RATE = 12;
-        private static final int MSG_CUSTOM_ACTION = 13;
-        private static final int MSG_MEDIA_BUTTON = 14;
-        private static final int MSG_COMMAND = 15;
-        private static final int MSG_ADJUST_VOLUME = 16;
-        private static final int MSG_SET_VOLUME = 17;
-        private static final int MSG_PLAY_URI = 18;
+        private static final int MSG_COMMAND = 1;
+        private static final int MSG_MEDIA_BUTTON = 2;
+        private static final int MSG_PREPARE = 3;
+        private static final int MSG_PREPARE_MEDIA_ID = 4;
+        private static final int MSG_PREPARE_SEARCH = 5;
+        private static final int MSG_PREPARE_URI = 6;
+        private static final int MSG_PLAY = 7;
+        private static final int MSG_PLAY_MEDIA_ID = 8;
+        private static final int MSG_PLAY_SEARCH = 9;
+        private static final int MSG_PLAY_URI = 10;
+        private static final int MSG_SKIP_TO_ITEM = 11;
+        private static final int MSG_PAUSE = 12;
+        private static final int MSG_STOP = 13;
+        private static final int MSG_NEXT = 14;
+        private static final int MSG_PREVIOUS = 15;
+        private static final int MSG_FAST_FORWARD = 16;
+        private static final int MSG_REWIND = 17;
+        private static final int MSG_SEEK_TO = 18;
+        private static final int MSG_RATE = 19;
+        private static final int MSG_CUSTOM_ACTION = 20;
+        private static final int MSG_ADJUST_VOLUME = 21;
+        private static final int MSG_SET_VOLUME = 22;
 
         private MediaSession.Callback mCallback;
 
@@ -1210,6 +1295,25 @@
         public void handleMessage(Message msg) {
             VolumeProvider vp;
             switch (msg.what) {
+                case MSG_COMMAND:
+                    Command cmd = (Command) msg.obj;
+                    mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
+                    break;
+                case MSG_MEDIA_BUTTON:
+                    mCallback.onMediaButtonEvent((Intent) msg.obj);
+                    break;
+                case MSG_PREPARE:
+                    mCallback.onPrepare();
+                    break;
+                case MSG_PREPARE_MEDIA_ID:
+                    mCallback.onPrepareFromMediaId((String) msg.obj, msg.getData());
+                    break;
+                case MSG_PREPARE_SEARCH:
+                    mCallback.onPrepareFromSearch((String) msg.obj, msg.getData());
+                    break;
+                case MSG_PREPARE_URI:
+                    mCallback.onPrepareFromUri((Uri) msg.obj, msg.getData());
+                    break;
                 case MSG_PLAY:
                     mCallback.onPlay();
                     break;
@@ -1252,13 +1356,6 @@
                 case MSG_CUSTOM_ACTION:
                     mCallback.onCustomAction((String) msg.obj, msg.getData());
                     break;
-                case MSG_MEDIA_BUTTON:
-                    mCallback.onMediaButtonEvent((Intent) msg.obj);
-                    break;
-                case MSG_COMMAND:
-                    Command cmd = (Command) msg.obj;
-                    mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
-                    break;
                 case MSG_ADJUST_VOLUME:
                     synchronized (mLock) {
                         vp = mVolumeProvider;
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 1079a1f..1485cd7 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -133,19 +133,32 @@
     public static final long ACTION_PLAY_FROM_URI = 1 << 13;
 
     /**
-     * Used as an optional boolean extra field in
-     * {@link MediaController.TransportControls#playFromMediaId},
-     * {@link MediaController.TransportControls#playFromSearch}, and
-     * {@link MediaController.TransportControls#playFromUri}. Value of {@code true} overrides
-     * the default behavior of starting the playback after preparing. Check
-     * {@link MediaSession#FLAG_HANDLES_PREPARE_ONLY} to see if the media session supports this.
+     * Indicates this session supports the prepare command.
      *
-     * @see MediaSession#FLAG_HANDLES_PREPARE_ONLY
-     * @see MediaController.TransportControls#playFromMediaId
-     * @see MediaController.TransportControls#playFromSearch
-     * @see MediaController.TransportControls#playFromUri
+     * @see Builder#setActions(long)
      */
-    public static final String EXTRA_PREPARE_ONLY = "android.media.session.extra.PREPARE_ONLY";
+    public static final long ACTION_PREPARE = 1 << 14;
+
+    /**
+     * Indicates this session supports the prepare from media id command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PREPARE_FROM_MEDIA_ID = 1 << 15;
+
+    /**
+     * Indicates this session supports the prepare from search command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PREPARE_FROM_SEARCH = 1 << 16;
+
+    /**
+     * Indicates this session supports the prepare from URI command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PREPARE_FROM_URI = 1 << 17;
 
     /**
      * This is the default playback state and indicates that no media has been
@@ -330,6 +343,10 @@
      * <li> {@link PlaybackState#STATE_REWINDING}</li>
      * <li> {@link PlaybackState#STATE_BUFFERING}</li>
      * <li> {@link PlaybackState#STATE_ERROR}</li>
+     * <li> {@link PlaybackState#STATE_CONNECTING}</li>
+     * <li> {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}</li>
+     * <li> {@link PlaybackState#STATE_SKIPPING_TO_NEXT}</li>
+     * <li> {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
      * </ul>
      */
     public int getState() {
@@ -380,6 +397,10 @@
      * <li> {@link PlaybackState#ACTION_PLAY_FROM_SEARCH}</li>
      * <li> {@link PlaybackState#ACTION_SKIP_TO_QUEUE_ITEM}</li>
      * <li> {@link PlaybackState#ACTION_PLAY_FROM_URI}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE_FROM_MEDIA_ID}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
      * </ul>
      */
     public long getActions() {
@@ -831,6 +852,10 @@
          * <li> {@link PlaybackState#STATE_REWINDING}</li>
          * <li> {@link PlaybackState#STATE_BUFFERING}</li>
          * <li> {@link PlaybackState#STATE_ERROR}</li>
+         * <li> {@link PlaybackState#STATE_CONNECTING}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_NEXT}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
          * </ul>
          *
          * @param state The current state of playback.
@@ -870,6 +895,10 @@
          * <li> {@link PlaybackState#STATE_REWINDING}</li>
          * <li> {@link PlaybackState#STATE_BUFFERING}</li>
          * <li> {@link PlaybackState#STATE_ERROR}</li>
+         * <li> {@link PlaybackState#STATE_CONNECTING}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_NEXT}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
          * </ul>
          *
          * @param state The current state of playback.
@@ -900,6 +929,10 @@
          * <li> {@link PlaybackState#ACTION_PLAY_FROM_SEARCH}</li>
          * <li> {@link PlaybackState#ACTION_SKIP_TO_QUEUE_ITEM}</li>
          * <li> {@link PlaybackState#ACTION_PLAY_FROM_URI}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE_FROM_MEDIA_ID}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
          * </ul>
          *
          * @param actions The set of actions allowed.
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 7b8e4b2..1c11842 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1314,6 +1314,8 @@
             private static final char COMMA = ',';
             private static final String DELIMITER = ",";
 
+            private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
             private Genres() {}
 
             /**
@@ -1359,6 +1361,12 @@
              * @return genre strings.
              */
             public static String[] decode(String genres) {
+                if (genres.isEmpty()) {
+                    return EMPTY_STRING_ARRAY;
+                }
+                if (genres.indexOf(COMMA) == -1 && genres.indexOf(DOUBLE_QUOTE) == -1) {
+                    return new String[] {genres.trim()};
+                }
                 StringBuilder sb = new StringBuilder();
                 List<String> results = new ArrayList<>();
                 int length = genres.length();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index fd96391..216509d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -18,6 +18,7 @@
 
 import static com.android.documentsui.Shared.DEBUG;
 import static com.android.documentsui.Shared.TAG;
+import static com.android.internal.util.Preconditions.checkState;
 
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
@@ -40,6 +41,7 @@
 
 import com.android.documentsui.model.RootInfo;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
@@ -85,15 +87,13 @@
 
         // Create a new anonymous "Recents" RootInfo. It's a faker.
         mRecentsRoot = new RootInfo() {{
-            // Special root for recents
-            authority = null;
-            rootId = null;
-            derivedIcon = R.drawable.ic_root_recent;
-            derivedType = RootInfo.TYPE_RECENTS;
-            flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD;
-            title = mContext.getString(R.string.root_recent);
-            availableBytes = -1;
-        }};
+                // Special root for recents
+                derivedIcon = R.drawable.ic_root_recent;
+                derivedType = RootInfo.TYPE_RECENTS;
+                flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD;
+                title = mContext.getString(R.string.root_recent);
+                availableBytes = -1;
+            }};
     }
 
     private class RootsChangedObserver extends ContentObserver {
@@ -116,6 +116,16 @@
      * Gather roots from all known storage providers.
      */
     public void updateAsync() {
+        // Verifying an assumption about the recents root being immutable.
+        if (DEBUG) {
+            checkState(mRecentsRoot.authority == null);
+            checkState(mRecentsRoot.rootId == null);
+            checkState(mRecentsRoot.derivedIcon == R.drawable.ic_root_recent);
+            checkState(mRecentsRoot.derivedType == RootInfo.TYPE_RECENTS);
+            checkState(mRecentsRoot.flags == (Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD));
+            checkState(mRecentsRoot.title == mContext.getString(R.string.root_recent));
+            checkState(mRecentsRoot.availableBytes == -1);
+        }
         new UpdateTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
@@ -412,9 +422,10 @@
             if (!state.showAdvanced && root.isAdvanced()) continue;
             // Exclude non-local devices when local only
             if (state.localOnly && !root.isLocalOnly()) continue;
-            // Exclude downloads roots that don't support directory creation
-            // TODO: Add flag to check the root supports directory creation or not.
-            if (state.directoryCopy && !root.supportsChildren()) continue;
+            // Exclude downloads roots as it doesn't support directory creation (actually
+            // we just don't show them).
+            // TODO: Add flag to check the root supports directory creation.
+            if (state.directoryCopy && !root.isDownloads()) continue;
 
             // Only show empty roots when creating, or in browse mode.
             if (root.isEmpty() && (state.action == State.ACTION_OPEN
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index f908eeb..9f83c04 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -45,7 +45,6 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.RootInfo;
 
 import java.util.ArrayList;
@@ -403,17 +402,7 @@
     public static class RootComparator implements Comparator<RootItem> {
         @Override
         public int compare(RootItem lhs, RootItem rhs) {
-            // Sort by root type, then title, then summary.
-            int score = lhs.root.derivedType - rhs.root.derivedType;
-            if (score != 0) {
-                return score;
-            }
-            score = DocumentInfo.compareToIgnoreCaseNullable(lhs.root.title, rhs.root.title);
-            if (score != 0) {
-                return score;
-            }
-
-            return DocumentInfo.compareToIgnoreCaseNullable(lhs.root.summary, rhs.root.summary);
+            return lhs.root.compareTo(rhs.root);
         }
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index 22cb25a..b90a119 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -17,14 +17,17 @@
 package com.android.documentsui;
 
 import android.content.Context;
+import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.text.format.Time;
 
+import java.text.Collator;
 import java.util.ArrayList;
 import java.util.List;
 
 /** @hide */
 public final class Shared {
+
     /** Intent action name to pick a copy destination. */
     public static final String ACTION_PICK_COPY_DESTINATION =
             "com.android.documentsui.PICK_COPY_DESTINATION";
@@ -39,6 +42,19 @@
     public static final String TAG = "Documents";
     public static final String EXTRA_STACK = "com.android.documentsui.STACK";
 
+
+    /**
+     * String prefix used to indicate the document is a directory.
+     */
+    public static final char DIR_PREFIX = '\001';
+
+    private static final Collator sCollator;
+
+    static {
+        sCollator = Collator.getInstance();
+        sCollator.setStrength(Collator.SECONDARY);
+    }
+
     /**
      * Generates a formatted quantity string.
      */
@@ -76,4 +92,26 @@
             ? (ArrayList<T>) list
             : new ArrayList<T>(list);
     }
+
+    /**
+     * Compare two strings against each other using system default collator in a
+     * case-insensitive mode. Clusters strings prefixed with {@link DIR_PREFIX}
+     * before other items.
+     */
+    public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
+        final boolean leftEmpty = TextUtils.isEmpty(lhs);
+        final boolean rightEmpty = TextUtils.isEmpty(rhs);
+
+        if (leftEmpty && rightEmpty) return 0;
+        if (leftEmpty) return -1;
+        if (rightEmpty) return 1;
+
+        final boolean leftDir = (lhs.charAt(0) == DIR_PREFIX);
+        final boolean rightDir = (rhs.charAt(0) == DIR_PREFIX);
+
+        if (leftDir && !rightDir) return -1;
+        if (rightDir && !leftDir) return 1;
+
+        return sCollator.compare(lhs, rhs);
+    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 0a9789f..4583dec 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -1071,8 +1071,8 @@
             return false;
         }
 
-        // Can't copy folders to roots that don't support children.
-        if (!root.supportsChildren()) {
+        // Can't copy folders to downloads, because we don't show folders there.
+        if (!root.isDownloads()) {
             for (DocumentInfo docs : files) {
                 if (docs.isDirectory()) {
                     return false;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
index b369448..9684a5a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
@@ -35,6 +35,7 @@
 
 import com.android.documentsui.DirectoryResult;
 import com.android.documentsui.RootCursorWrapper;
+import com.android.documentsui.Shared;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 import com.android.documentsui.model.DocumentInfo;
 
@@ -170,7 +171,7 @@
                     final String displayName = getCursorString(
                             mCursor, Document.COLUMN_DISPLAY_NAME);
                     if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-                        stringValues[pos] = DocumentInfo.DIR_PREFIX + displayName;
+                        stringValues[pos] = Shared.DIR_PREFIX + displayName;
                     } else {
                         stringValues[pos] = displayName;
                     }
@@ -227,7 +228,7 @@
 
                 final String lhs = pivotValue;
                 final String rhs = sortKey[mid];
-                final int compare = DocumentInfo.compareToIgnoreCaseNullable(lhs, rhs);
+                final int compare = Shared.compareToIgnoreCaseNullable(lhs, rhs);
 
                 if (compare < 0) {
                     right = mid;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 1c696ad..e9fdab0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -26,7 +26,6 @@
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsProvider;
 import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
 
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.RootCursorWrapper;
@@ -38,7 +37,6 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.ProtocolException;
-import java.text.Collator;
 import java.util.Objects;
 
 /**
@@ -48,13 +46,6 @@
     private static final int VERSION_INIT = 1;
     private static final int VERSION_SPLIT_URI = 2;
 
-    private static final Collator sCollator;
-
-    static {
-        sCollator = Collator.getInstance();
-        sCollator.setStrength(Collator.SECONDARY);
-    }
-
     public String authority;
     public String documentId;
     public String mimeType;
@@ -320,31 +311,4 @@
         fnfe.initCause(t);
         throw fnfe;
     }
-
-    /**
-     * String prefix used to indicate the document is a directory.
-     */
-    public static final char DIR_PREFIX = '\001';
-
-    /**
-     * Compare two strings against each other using system default collator in a
-     * case-insensitive mode. Clusters strings prefixed with {@link #DIR_PREFIX}
-     * before other items.
-     */
-    public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
-        final boolean leftEmpty = TextUtils.isEmpty(lhs);
-        final boolean rightEmpty = TextUtils.isEmpty(rhs);
-
-        if (leftEmpty && rightEmpty) return 0;
-        if (leftEmpty) return -1;
-        if (rightEmpty) return 1;
-
-        final boolean leftDir = (lhs.charAt(0) == DIR_PREFIX);
-        final boolean rightDir = (rhs.charAt(0) == DIR_PREFIX);
-
-        if (leftDir && !rightDir) return -1;
-        if (rightDir && !leftDir) return 1;
-
-        return sCollator.compare(lhs, rhs);
-    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 3f4a1df..3897058 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -16,10 +16,12 @@
 
 package com.android.documentsui.model;
 
+import static com.android.documentsui.Shared.compareToIgnoreCaseNullable;
 import static com.android.documentsui.model.DocumentInfo.getCursorInt;
 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.drawable.Drawable;
@@ -36,17 +38,31 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.ProtocolException;
 import java.util.Objects;
 
 /**
  * Representation of a {@link Root}.
  */
-public class RootInfo implements Durable, Parcelable {
+public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
     private static final int VERSION_INIT = 1;
     private static final int VERSION_DROP_TYPE = 2;
 
     // The values of these constants determine the sort order of various roots in the RootsFragment.
+    @IntDef(flag = true, value = {
+            TYPE_IMAGES,
+            TYPE_VIDEO,
+            TYPE_AUDIO,
+            TYPE_RECENTS,
+            TYPE_DOWNLOADS,
+            TYPE_LOCAL,
+            TYPE_MTP,
+            TYPE_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RootType {}
     public static final int TYPE_IMAGES = 1;
     public static final int TYPE_VIDEO = 2;
     public static final int TYPE_AUDIO = 3;
@@ -69,7 +85,7 @@
     /** Derived fields that aren't persisted */
     public String[] derivedMimeTypes;
     public int derivedIcon;
-    public int derivedType;
+    public @RootType int derivedType;
 
     public RootInfo() {
         reset();
@@ -329,6 +345,22 @@
     }
 
     @Override
+    public int compareTo(RootInfo other) {
+        // Sort by root type, then title, then summary.
+        int score = derivedType - other.derivedType;
+        if (score != 0) {
+            return score;
+        }
+
+        score = compareToIgnoreCaseNullable(title, other.title);
+        if (score != 0) {
+            return score;
+        }
+
+        return compareToIgnoreCaseNullable(summary, other.summary);
+    }
+
+    @Override
     public String toString() {
         return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
     }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
index 83299f0..4b0bc41 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
@@ -28,6 +28,7 @@
 
 import com.android.documentsui.DirectoryResult;
 import com.android.documentsui.RootCursorWrapper;
+import com.android.documentsui.Shared;
 import com.android.documentsui.State;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 import com.android.documentsui.model.DocumentInfo;
@@ -190,7 +191,7 @@
 
         assertEquals(ITEM_COUNT, seen.cardinality());
         for (int i = 0; i < names.size()-1; ++i) {
-            assertTrue(DocumentInfo.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) <= 0);
+            assertTrue(Shared.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) <= 0);
         }
     }
 
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
index 441b9a7..ca5c799 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
@@ -581,6 +581,23 @@
         }
     }
 
+    void updateObject(String documentId, int deviceId, String parentId, MtpObjectInfo info) {
+        final ContentValues values = new ContentValues();
+        getObjectDocumentValues(values, deviceId, parentId, info);
+
+        mDatabase.beginTransaction();
+        try {
+            mDatabase.update(
+                    TABLE_DOCUMENTS,
+                    values,
+                    Document.COLUMN_DOCUMENT_ID + " = ?",
+                    strings(documentId));
+            mDatabase.setTransactionSuccessful();
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
     private static class OpenHelper extends SQLiteOpenHelper {
         public OpenHelper(Context context, int flags) {
             super(context,
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index db1671d..d329e3c 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -486,7 +486,7 @@
         public final DocumentLoader mDocumentLoader;
 
         public DeviceToolkit(MtpManager manager, ContentResolver resolver, MtpDatabase database) {
-            mPipeManager = new PipeManager();
+            mPipeManager = new PipeManager(database);
             mDocumentLoader = new DocumentLoader(manager, resolver, database);
         }
     }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
index 16523bc..645bfcd 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
@@ -29,12 +29,14 @@
 
 class PipeManager {
     final ExecutorService mExecutor;
+    final MtpDatabase mDatabase;
 
-    PipeManager() {
-        this(Executors.newSingleThreadExecutor());
+    PipeManager(MtpDatabase database) {
+        this(database, Executors.newSingleThreadExecutor());
     }
 
-    PipeManager(ExecutorService executor) {
+    PipeManager(MtpDatabase database, ExecutorService executor) {
+        this.mDatabase = database;
         this.mExecutor = executor;
     }
 
@@ -46,7 +48,7 @@
 
     ParcelFileDescriptor writeDocument(Context context, MtpManager model, Identifier identifier)
             throws IOException {
-        final Task task = new WriteDocumentTask(context, model, identifier);
+        final Task task = new WriteDocumentTask(context, model, identifier, mDatabase);
         mExecutor.execute(task);
         return task.getWritingFileDescriptor();
     }
@@ -100,11 +102,14 @@
 
     private static class WriteDocumentTask extends Task {
         private final Context mContext;
+        private final MtpDatabase mDatabase;
 
-        WriteDocumentTask(Context context, MtpManager model, Identifier identifier)
+        WriteDocumentTask(
+                Context context, MtpManager model, Identifier identifier, MtpDatabase database)
                 throws IOException {
             super(model, identifier);
             mContext = context;
+            mDatabase = database;
         }
 
         @Override
@@ -112,7 +117,7 @@
             File tempFile = null;
             try {
                 // Obtain a temporary file and copy the data to it.
-                tempFile = mContext.getCacheDir().createTempFile("mtp", "tmp");
+                tempFile = File.createTempFile("mtp", "tmp", mContext.getCacheDir());
                 try (
                     final FileOutputStream tempOutputStream =
                             new ParcelFileDescriptor.AutoCloseOutputStream(
@@ -140,12 +145,22 @@
                 // Create the target object info with a correct file size and upload the file.
                 final MtpObjectInfo targetObjectInfo =
                         new MtpObjectInfo.Builder(placeholderObjectInfo)
-                                .setCompressedSize((int) tempFile.length())
+                                .setCompressedSize(tempFile.length())
                                 .build();
                 final ParcelFileDescriptor tempInputDescriptor = ParcelFileDescriptor.open(
                         tempFile, ParcelFileDescriptor.MODE_READ_ONLY);
-                mManager.createDocument(mIdentifier.mDeviceId,
-                        targetObjectInfo, tempInputDescriptor);
+                final int newObjectHandle = mManager.createDocument(
+                        mIdentifier.mDeviceId, targetObjectInfo, tempInputDescriptor);
+
+                final MtpObjectInfo newObjectInfo = mManager.getObjectInfo(
+                        mIdentifier.mDeviceId, newObjectHandle);
+                final Identifier parentIdentifier =
+                        mDatabase.getParentIdentifier(mIdentifier.mDocumentId);
+                mDatabase.updateObject(
+                        mIdentifier.mDocumentId,
+                        mIdentifier.mDeviceId,
+                        parentIdentifier.mDocumentId,
+                        newObjectInfo);
             } catch (IOException error) {
                 Log.w(MtpDocumentsProvider.TAG,
                         "Failed to send a file because of: " + error.getMessage());
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index 1df7351..05c9c57 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -983,18 +983,10 @@
     }
 
     private void addTestDevice() throws FileNotFoundException {
-        mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
-                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
-                null));
-        mDatabase.getMapper().stopAddingDocuments(null);
+        TestUtil.addTestDevice(mDatabase);
     }
 
     private void addTestStorage(String parentId) throws FileNotFoundException {
-        mDatabase.getMapper().startAddingDocuments(parentId);
-        mDatabase.getMapper().putStorageDocuments(parentId, new MtpRoot[] {
-                new MtpRoot(0, 100, "Storage", 1024, 1024, ""),
-        });
-        mDatabase.getMapper().stopAddingDocuments(parentId);
+        TestUtil.addTestStorage(mDatabase, parentId);
     }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
index 4dfc785..94f87ff 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
@@ -16,8 +16,10 @@
 
 package com.android.mtp;
 
+import android.database.Cursor;
 import android.mtp.MtpObjectInfo;
 import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract.Document;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
@@ -33,12 +35,14 @@
     private TestMtpManager mtpManager;
     private ExecutorService mExecutor;
     private PipeManager mPipeManager;
+    private MtpDatabase mDatabase;
 
     @Override
     public void setUp() {
         mtpManager = new TestMtpManager(getContext());
         mExecutor = Executors.newSingleThreadExecutor();
-        mPipeManager = new PipeManager(mExecutor);
+        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        mPipeManager = new PipeManager(mDatabase, mExecutor);
     }
 
     public void testReadDocument_basic() throws Exception {
@@ -57,25 +61,32 @@
     }
 
     public void testWriteDocument_basic() throws Exception {
+        TestUtil.addTestDevice(mDatabase);
+        TestUtil.addTestStorage(mDatabase, "1");
+
+        final MtpObjectInfo info =
+                new MtpObjectInfo.Builder().setObjectHandle(1).setName("note.txt").build();
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] { info });
+        mDatabase.getMapper().stopAddingDocuments("2");
         // Create a placeholder file which should be replaced by a real file later.
-        mtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
-                .setObjectHandle(1)
-                .build());
+        mtpManager.setObjectInfo(0, info);
 
         // Upload testing bytes.
         final ParcelFileDescriptor descriptor = mPipeManager.writeDocument(
                 getContext(),
                 mtpManager,
-                new Identifier(0, 0, 1, null, MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT));
+                new Identifier(0, 0, 1, "2", MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT));
         final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
                 new ParcelFileDescriptor.AutoCloseOutputStream(descriptor);
         outputStream.write(HELLO_BYTES, 0, HELLO_BYTES.length);
         outputStream.close();
-        mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
+        mExecutor.shutdown();
+        assertTrue(mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS));
 
         // Check if the placeholder file is removed.
         try {
-            final MtpObjectInfo placeholderDocument = mtpManager.getObjectInfo(0, 1);
+            mtpManager.getObjectInfo(0, 1);
             fail();  // The placeholder file has not been deleted.
         } catch (IOException e) {
             // Expected error, as the file is gone.
@@ -86,6 +97,14 @@
                 0, TestMtpManager.CREATED_DOCUMENT_HANDLE);
         assertTrue(targetDocument != null);
 
+        // Confirm the object handle is updated.
+        try (final Cursor cursor = mDatabase.queryDocument(
+                "2", new String[] { MtpDatabaseConstants.COLUMN_OBJECT_HANDLE })) {
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals(TestMtpManager.CREATED_DOCUMENT_HANDLE, cursor.getInt(0));
+        }
+
         // Verify uploaded bytes.
         final byte[] uploadedBytes = mtpManager.getImportFileBytes(
                 0, TestMtpManager.CREATED_DOCUMENT_HANDLE);
@@ -112,7 +131,8 @@
 
     private void assertDescriptor(ParcelFileDescriptor descriptor, byte[] expectedBytes)
             throws IOException, InterruptedException {
-        mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
+        mExecutor.shutdown();
+        assertTrue(mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS));
         try (final ParcelFileDescriptor.AutoCloseInputStream stream =
                 new ParcelFileDescriptor.AutoCloseInputStream(descriptor)) {
             byte[] results = new byte[100];
@@ -125,7 +145,8 @@
 
     private void assertDescriptorError(ParcelFileDescriptor descriptor)
             throws InterruptedException {
-        mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
+        mExecutor.shutdown();
+        assertTrue(mExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS));
         try {
             descriptor.checkError();
             fail();
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
index 4378152..1b46f3c 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -149,7 +149,9 @@
         if (mObjectInfos.containsKey(key)) {
             throw new IOException();
         }
-        mObjectInfos.put(key, objectInfo);
+        final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo).
+                setObjectHandle(CREATED_DOCUMENT_HANDLE).build();
+        mObjectInfos.put(key, newInfo);
         if (objectInfo.getFormat() != 0x3001) {
             try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
                     new ParcelFileDescriptor.AutoCloseInputStream(source)) {
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
index ffcc088..34dd77b 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
@@ -21,12 +21,11 @@
 import android.hardware.usb.UsbManager;
 import android.os.SystemClock;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Objects;
 
-import junit.framework.Assert;
-
 /**
  * Static utility methods for testing.
  */
@@ -57,6 +56,22 @@
         }
     }
 
+    static void addTestDevice(MtpDatabase database) throws FileNotFoundException {
+        database.getMapper().startAddingDocuments(null);
+        database.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
+                null));
+        database.getMapper().stopAddingDocuments(null);
+    }
+
+    static void addTestStorage(MtpDatabase database, String parentId) throws FileNotFoundException {
+        database.getMapper().startAddingDocuments(parentId);
+        database.getMapper().putStorageDocuments(parentId, new MtpRoot[] {
+                new MtpRoot(0, 100, "Storage", 1024, 1024, ""),
+        });
+        database.getMapper().stopAddingDocuments(parentId);
+    }
+
     private static UsbDevice findMtpDevice(
             UsbManager usbManager,
             MtpManager manager) throws IOException {
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 2ddb1e9..99699b9 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Programme verplig ekstern toegelaat"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Laat enige program na ekstern geskryf word, ongeag manifeswaardes"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Verplig verstelbare groottes vir aktiwiteite"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Maak grootte van alle aktiwiteite verstelbaar vir veelvuldige vensters, ongeag manifeswaardes."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Maak die groottes van alle aktiwiteite verstelbaar vir veelvuldige vensters, ongeag manifeswaardes."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Aktiveer vormvrye-Windows"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktiveer steun vir eksperimentele vormvrye-Windows."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktiveer steun vir eksperimentele vormvrye-Windows."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Werkskerm-rugsteunwagwoord"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Volle rekenaarrugsteune word nie tans beskerm nie"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tik om die wagwoord vir volledige rekenaarrugsteune te verander of te verwyder"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Gedeaktiveer"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Altyd aan"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Outomaties"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Stel WebView-implementering"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Die gekose WebView-toepassing is gedeaktiveer, maar moet geaktiveer wees om gebruik te word. Wil jy dit aktiveer?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurregstelling"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierdie kenmerk is eksperimenteel en kan werkverrigting beïnvloed."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ongeveer <xliff:g id="TIME">%1$s</xliff:g> oor"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – sowat <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Gedeaktiveer deur administrateur"</string>
     <string name="home" msgid="8263346537524314127">"Tuis"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> gelede"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> oor"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 4276bea..0e363b5 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"በውጫዊ ላይ ሃይል ይፈቀዳል"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"አንጸባራቂ እሴቶች ግምት ውስጥ ሳይገቡ ማንኛውም መተግበሪያ ወደ ውጫዊ ማከማቻ ለመጻፍ ብቁ ያደርጋል።"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"እንቅስቃሴዎች ዳግመኛ እንዲመጣጠኑ አስገድድ"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"የዝርዝር ሰነድ እሴቶች ምንም ይሁኑ ምን ለበርካታ መስኮቶች ሁሉንም እንቅስቃሴዎች ዳግም የሚመጣጠኑ እንዲሆኑ ያደርጋቸዋል።"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"የዝርዝር ሰነድ እሴቶች ምንም ይሁኑ ምን ለበርካታ መስኮቶች ሁሉንም እንቅስቃሴዎች መጠናቸው የሚቀየሩ እንዲሆኑ ያደርጋቸዋል።"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"የነጻ ቅርጽ መስኮቶችን ያንቁ"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"የሙከራ ነጻ ቅርጽ መስኮቶች ድጋፍን ያነቃል።"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"የሙከራ ነጻ መልክ መስኮቶች ድጋፍን አንቃ"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"የዴስክቶፕ መጠባበቂያ ይለፍ ቃል"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ዴስክቶፕ ሙሉ ምትኬዎች በአሁኑ ሰዓት አልተጠበቁም"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"የዴስክቶፕ ሙሉ ምትኬዎች የይለፍ ቃሉን ለመለወጥ ወይም ለማስወገድ ነካ ያድርጉ"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"ተሰናክሏል"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"ሁልጊዜ ይበራል"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ራስ-ሰር"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"የWebView ትግበራ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"የWebView ትግበራን ያዘጋጁ"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"የተመረጠው WebView ትግበራ ተሰናክሏል፣ እና ጥቅም ላይ እንዲውል መንቃት አለበት፣ ሊያነቁት ይፈልጋሉ?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"የቀለም ማስተካከያ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ይህ ባህሪ የሙከራ ነውና አፈጻጸም ላይ ተጽዕኖ ሊኖረው ይችላል።"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> ገደማ ቀርቷል"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ገደማ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> እስከሚሞላ ድረስ"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"በአስተዳዳሪ የተሰናከለ"</string>
     <string name="home" msgid="8263346537524314127">"መነሻ"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"ከ<xliff:g id="ID_1">%1$s</xliff:g> በፊት"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ቀርቷል"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 67fb59c..c757b71 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"فرض السماح للتطبيقات على الخارجي"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"تأهيل أي تطبيق بحيث تتم كتابته على سعة تخزين خارجية، بغض النظر عن قيم البيان"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"فرض إمكانية تغيير على الأنشطة"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"لتمكين تغيير حجم جميع الأنشطة لتناسب تعدد النوافذ، بغض النظر عن قيم البيان."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"تمكين تغيير حجم جميع الأنشطة لتناسب تعدد النوافذ، بغض النظر عن قيم البيان."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"تمكين النوافذ الحرة"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"لتمكين إتاحة استخدام النوافذ الحرة التجريبية."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"تمكين إتاحة استخدام النوافذ الحرة التجريبية."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"كلمة مرور احتياطية للكمبيوتر"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"النسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"معطَّل"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"التشغيل دائمًا"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"تلقائيًا"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"‏تطبيق WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"‏تعيين تطبيق WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"‏إن تنفيذ ميزة WebView التي تم اختيارها معطَّل، ويجب تمكين هذه الميزة ليتسنى استخدامها، فهل تريد تمكينها؟"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحيح الألوان"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"هذه الميزة تجريبية وقد تؤثر في الأداء."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> تقريبًا"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"تم التعطيل بواسطة المشرف"</string>
     <string name="home" msgid="8263346537524314127">"الشاشة الرئيسية"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"قبل <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"يتبقى <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index 12b077e..61008b9 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Tətbiqlərə xaricdən məcburi icazə"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Seçilmiş hər hansı tətbiqi bəyannamə dəyərlərindən aslı olmayaraq xarici yaddaşa yazılabilən edir."</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Ölçü dəyişdirmək üçün məcburi fəaliyyətlər"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Bəyannamə dəyərlərindən aslı olmayaraq bütün fəaliyyətləri çoxsaylı pəncərə üçün dəyişkən ölçülü edir."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Bəyannamə dəyərlərindən aslı olmayaraq, bütün fəaliyyətləri çoxsaylı pəncərə üçün dəyişkən ölçülü edin."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Freeform windows aktiv edin"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Sınaq üçün freeform windows aktiv edir"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Sınaq üçün freeform windows aktiv edilir."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Masaüstü rezerv parolu"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Masaüstü tam rezervlər hazırda qorunmayıblar."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Masaüstünün tam rezerv kopyalanması üçün parolu dəyişmək və ya silmək üçün basın"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Qeyri-aktiv"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Həmişə aktiv"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Avtomatik"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView icrası"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView icrasını ayarlayın"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Seçilmiş WebView icrası deaktiv edildi, istifadəsi üçün aktiv edilməlidir, aktivləşdirmək istəyirsiniz?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rəng düzəlişi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya eksperimentaldır və performansa təsir edə bilər."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> dolana qədər"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index ae56978..7021ca6 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Prinudno dozvoli aplikacije u spoljnoj"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Prinudno omogući promenu veličine aktivnosti"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Omogućava promenu veličine svih aktivnosti za režim sa više prozora, bez obzira na vrednosti manifesta."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Omogući promenu veličine svih aktivnosti za režim sa više prozora, bez obzira na vrednosti manifesta."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Omogući prozore proizvoljnog formata"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Omogućava podršku za eksperimentalne prozore proizvoljnog formata."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Omogućite podršku za eksperimentalne prozore proizvoljnog formata."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka rezervne kopije za računar"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Rezervne kopije čitavog sistema trenutno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da biste promenili ili uklonili lozinku za pravljenje rezervnih kopija čitavog sistema na računaru"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Onemogućeno"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Uvek uključeno"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatski"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Primena WebView-a"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Podesite primenu WebView-a"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Izabrana primena WebView-a je onemogućena, a mora da bude omogućena radi korišćenja. Želite li da je omogućite?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boja"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo oko <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Onemogućio je administrator"</string>
     <string name="home" msgid="8263346537524314127">"Početni"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Pre <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index ad0ace4..df47ad9 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Външно хран.: Принуд. разрешаване на приложенията"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Позволява прилож. да се записват във външ. хранил. независимо от стойностите в манифеста"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Възможност за преоразмеряване на активностите"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Дава възможност за преоразмеряване на всички активности в режима за няколко прозореца независимо от стойностите в манифеста."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Дава възможност за преоразмеряване на всички активности в режима за няколко прозореца независимо от стойностите в манифеста."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Активиране на прозорците в свободна форма"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Активира поддръжката за експерименталните прозорци в свободна форма."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Активиране на поддръжката за експерименталните прозорци в свободна форма."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Наст. комп.: Парола"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Понастоящем пълните резервни копия за настолен компютър не са защитени"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Докоснете, за да промените или премахнете паролата за пълни резервни копия на настолния компютър"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Деактивирано"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Винаги включено"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Автоматично"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Внедряване на WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Задаване на внедряването на WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Избраното внедряване на WebView е деактивирано и трябва да го активирате, за да се използва. Искате ли да го направите?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекция на цветове"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Прибл. оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – приблизително оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Деактивирано от администратора"</string>
     <string name="home" msgid="8263346537524314127">"Начало"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Преди <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Оставащо време: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index 589c52e..e982a36 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"বহিরাগততে বলপূর্বক মঞ্জুরি"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ম্যানিফেস্ট মানগুলি নির্বিশেষে যেকোনো অ্যাপ্লিকেশানকে বাহ্যিক সঞ্চয়স্থানে লেখার উপযুক্ত বানায়"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"আকার পরিবর্তনযোগ্য করার জন্য ক্রিয়াকলাপগুলিকে জোর করুন"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"ম্যানিফেস্ট মানগুলির নির্বিশেষে মাল্টি-উইন্ডোর জন্য সমস্ত ক্রিয়াকলাপগুলিকে আকার পরিবর্তনযোগ্য করে তোলে৷"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ম্যানিফেস্ট মানগুলির নির্বিশেষে মাল্টি-উইন্ডোর জন্য সমস্ত ক্রিয়াকলাপগুলিকে আকার পরিবর্তনযোগ্য করুন৷"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"ফ্রি-ফর্ম উইন্ডোগুলি সক্ষম করুন"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"পরীক্ষামূলক ফ্রি-ফর্ম উইন্ডোগুলির জন্য সহায়তা সক্ষম করুন৷"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"পরীক্ষামূলক ফ্রি-ফর্ম উইন্ডোগুলির জন্য সহায়তা সক্ষম করুন৷"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ডেস্কটপ ব্যাকআপ পাসওয়ার্ড"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ডেস্কটপ পূর্ণ ব্যাকআপ বর্তমানে সুরক্ষিত নয়"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ডেস্কটপের সম্পূর্ণ ব্যাকআপের পাসওয়ার্ডটি পরিবর্তন করতে বা মুছে ফেলতে আলতো চাপুন"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"অক্ষম করা রয়েছে"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"সবসময় চালু"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"স্বয়ংক্রিয়"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"ওয়েবভিউ প্রয়োগ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"ওয়েবভিউ প্রয়োগ সেট করুন"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"নির্বাচিত ওয়েবভিউ প্রয়োগটি অক্ষম করা আছে এবং ব্যবহার করার জন্য অবশ্যই সক্ষম করতে হবে, আপনি কি এটিকে সক্ষম করতে চান?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"রঙ সংশোধন"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই বৈশিষ্ট্যটি পরীক্ষামূলক এবং এটি কার্য-সম্পাদনা প্রভাবিত করতে পারে।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"প্রায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"প্রায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - আনুমানিক <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string>
diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml
index 8da12cb..92c7ec8 100644
--- a/packages/SettingsLib/res/values-bs-rBA/strings.xml
+++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml
@@ -20,130 +20,69 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for wifi_fail_to_scan (1265540342578081461) -->
-    <skip />
-    <!-- no translation found for wifi_security_none (7985461072596594400) -->
-    <skip />
-    <!-- no translation found for wifi_remembered (4955746899347821096) -->
-    <skip />
-    <!-- no translation found for wifi_disabled_generic (4259794910584943386) -->
-    <skip />
-    <!-- no translation found for wifi_disabled_network_failure (2364951338436007124) -->
-    <skip />
-    <!-- no translation found for wifi_disabled_wifi_failure (3081668066612876581) -->
-    <skip />
-    <!-- no translation found for wifi_disabled_password_failure (8659805351763133575) -->
-    <skip />
-    <!-- no translation found for wifi_not_in_range (1136191511238508967) -->
-    <skip />
-    <!-- no translation found for wifi_no_internet (9151470775868728896) -->
-    <skip />
-    <!-- no translation found for saved_network (4352716707126620811) -->
-    <skip />
-    <!-- no translation found for connected_via_wfa (3805736726317410714) -->
-    <skip />
-    <!-- no translation found for connected_via_passpoint (2826205693803088747) -->
-    <skip />
-    <!-- no translation found for available_via_passpoint (1617440946846329613) -->
-    <skip />
-    <!-- no translation found for wifi_connected_no_internet (3149853966840874992) -->
-    <skip />
-    <!-- no translation found for bluetooth_disconnected (6557104142667339895) -->
-    <skip />
-    <!-- no translation found for bluetooth_disconnecting (8913264760027764974) -->
-    <skip />
-    <!-- no translation found for bluetooth_connecting (8555009514614320497) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected (6038755206916626419) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing (1426882272690346242) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset (2866994875046035609) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp (4576188601581440337) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_map (6504436917057479986) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (9195757766755553810) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_a2dp (2031475486179830674) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_headset (8658779596261212609) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_opp (9168139293654233697) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_hid (3680729023366986480) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_pan (3391606497945147673) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_pbap (5372051906968576809) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_pbap_summary (6605229608108852198) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_pan_nap (8429049285027482959) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_map (5465271250454324383) -->
-    <skip />
-    <!-- no translation found for bluetooth_profile_sap (5764222021851283125) -->
-    <skip />
-    <!-- no translation found for bluetooth_a2dp_profile_summary_connected (963376081347721598) -->
-    <skip />
-    <!-- no translation found for bluetooth_headset_profile_summary_connected (7661070206715520671) -->
-    <skip />
-    <!-- no translation found for bluetooth_opp_profile_summary_connected (2611913495968309066) -->
-    <skip />
-    <!-- no translation found for bluetooth_map_profile_summary_connected (8191407438851351713) -->
-    <skip />
-    <!-- no translation found for bluetooth_sap_profile_summary_connected (8561765057453083838) -->
-    <skip />
-    <!-- no translation found for bluetooth_opp_profile_summary_not_connected (1267091356089086285) -->
-    <skip />
-    <!-- no translation found for bluetooth_hid_profile_summary_connected (3381760054215168689) -->
-    <skip />
+    <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ne može skenirati mreže"</string>
+    <string name="wifi_security_none" msgid="7985461072596594400">"Nema"</string>
+    <string name="wifi_remembered" msgid="4955746899347821096">"Sačuvano"</string>
+    <string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogućeno"</string>
+    <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Greška u konfiguraciji IP-a"</string>
+    <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Greška pri povezivanju na Wi-Fi"</string>
+    <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem pri provjeri vjerodostojnosti."</string>
+    <string name="wifi_not_in_range" msgid="1136191511238508967">"Nije u dometu"</string>
+    <string name="wifi_no_internet" msgid="9151470775868728896">"Pristup internetu nije pronađen. Neće se ponovo povezivati automatski."</string>
+    <string name="saved_network" msgid="4352716707126620811">"Sačuvao <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_via_wfa" msgid="3805736726317410714">"Povezani preko Wi-Fi pomoćnika"</string>
+    <string name="connected_via_passpoint" msgid="2826205693803088747">"Povezani preko %1$s"</string>
+    <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string>
+    <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Povezano. Nema interneta"</string>
+    <string name="bluetooth_disconnected" msgid="6557104142667339895">"Isključen"</string>
+    <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prekidanje veze…"</string>
+    <string name="bluetooth_connecting" msgid="8555009514614320497">"Povezivanje…"</string>
+    <string name="bluetooth_connected" msgid="6038755206916626419">"Povezano"</string>
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"Uparivanje…"</string>
+    <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Povezano (bez telefona)"</string>
+    <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Povezano (bez medija)"</string>
+    <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezano (bez pristupa porukama)"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezano (bez zvuka telefona ili medija)"</string>
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string>
+    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefona"</string>
+    <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenošenje fajla"</string>
+    <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ulazni uređaj"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Pristup internetu"</string>
+    <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Dijeljenje kontakta"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Koristi za dijeljenje kontakta"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Dijeljenje internet veze"</string>
+    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Pristup poruci"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Pristup SIM-u"</string>
+    <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezano sa zvukom medija"</string>
+    <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezano na zvuk telefona"</string>
+    <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezan na server za prijenos podataka"</string>
+    <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"Povezano na mapu"</string>
+    <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"Povezan na SAP"</string>
+    <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Nije povezan na server za prijenos podataka"</string>
+    <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Spojen na ulazni uređaj"</string>
     <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"Pov. na ur. za pris. int."</string>
     <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"Dij. lok. int. veze s ur."</string>
-    <!-- no translation found for bluetooth_pan_profile_summary_use_for (5664884523822068653) -->
-    <skip />
-    <!-- no translation found for bluetooth_map_profile_summary_use_for (5154200119919927434) -->
-    <skip />
-    <!-- no translation found for bluetooth_sap_profile_summary_use_for (7085362712786907993) -->
-    <skip />
-    <!-- no translation found for bluetooth_a2dp_profile_summary_use_for (4630849022250168427) -->
-    <skip />
-    <!-- no translation found for bluetooth_headset_profile_summary_use_for (8705753622443862627) -->
-    <skip />
-    <!-- no translation found for bluetooth_opp_profile_summary_use_for (1255674547144769756) -->
-    <skip />
-    <!-- no translation found for bluetooth_hid_profile_summary_use_for (232727040453645139) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_accept (6163520056536604875) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_accept_all_caps (6061699265220789149) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_decline (4185420413578948140) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_will_share_phonebook (4982239145676394429) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_error_message (3748157733635947087) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_pin_error_message (8337234855188925274) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_device_down_error_message (7870998403045801381) -->
-    <skip />
-    <!-- no translation found for bluetooth_pairing_rejected_error_message (1648157108520832454) -->
-    <skip />
-    <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
-    <skip />
-    <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
-    <skip />
-    <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
-    <skip />
-    <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
-    <skip />
-    <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
-    <skip />
-    <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
-    <skip />
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"Koristi za pristup internetu"</string>
+    <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Koristi za mapu"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Koristi za pristup SIM-u"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Koristi za zvuk medija"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Koristi za zvuk telefona"</string>
+    <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Koristi za prijenos fajlova"</string>
+    <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Koristi kao ulaz"</string>
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Upari"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"UPARI"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Otkaži"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Uparivanje odobrava pristup kontaktima i istoriji poziva kada je uspostavljeno."</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Nije se moguće upariti s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nije se moguće upariti s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> zbog pogrešnog PIN-a ili pristupnog koda."</string>
+    <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Ne može komunicirati sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Uređaj <xliff:g id="DEVICE_NAME">%1$s</xliff:g> je odbio uparivanje."</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi isključen."</string>
+    <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi nije povezan."</string>
+    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi jedna crtica."</string>
+    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi dvije crtice."</string>
+    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi tri crtice."</string>
+    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi puni signal."</string>
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Uklonjene aplikacije"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Uklonjene aplikacije i korisnici"</string>
@@ -177,27 +116,27 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> je u potpunosti podržan"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> zahtjeva mrežnu vezu"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> nije podržan"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Provjerava se…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Postavke za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Pokreni postavke programa"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željeni program"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Opće"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Veoma sporo"</item>
+    <item msgid="4795095314303559268">"Sporo"</item>
+    <item msgid="8903157781070679765">"Normalno"</item>
+    <item msgid="164347302621392996">"Brzo"</item>
+    <item msgid="5794028588101562009">"Brže"</item>
+    <item msgid="7163942783888652942">"Veoma brzo"</item>
+    <item msgid="7831712693748700507">"Ubrzano"</item>
+    <item msgid="5194774745031751806">"Veoma ubrzano"</item>
+    <item msgid="9085102246155045744">"Najbrže"</item>
+  </string-array>
     <string name="choose_profile" msgid="8229363046053568878">"Odaberite profil"</string>
     <string name="category_personal" msgid="1299663247844969448">"Lično"</string>
     <string name="category_work" msgid="8699184680584175622">"Posao"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcije za programere"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Omogući opcije za programere"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Postavi opcije za razvoj aplikacija"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Opcije za programere nisu dostupne za ovog korisnika"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN postavke nisu dostupne za ovog korisnika"</string>
@@ -306,18 +245,12 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje procesa u pozadini"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Prik. dijalog Aplikacija ne reagira za apl. u poz."</string>
-    <!-- no translation found for force_allow_on_external (3215759785081916381) -->
-    <skip />
-    <!-- no translation found for force_allow_on_external_summary (3191952505860343233) -->
-    <skip />
-    <!-- no translation found for force_resizable_activities (8615764378147824985) -->
-    <skip />
-    <!-- no translation found for force_resizable_activities_summary (4508217476997182216) -->
-    <skip />
-    <!-- no translation found for enable_freeform_support (1461893351278940416) -->
-    <skip />
-    <!-- no translation found for enable_freeform_support_summary (2252563497485436534) -->
-    <skip />
+    <string name="force_allow_on_external" msgid="3215759785081916381">"Nametni aplikacije na vanjskoj pohrani"</string>
+    <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Dozvoljava da bilo koja aplikacija bude upisana na vanjsku pohranu, bez obzira na vrijednosti manifesta."</string>
+    <string name="force_resizable_activities" msgid="8615764378147824985">"Nametni aktivnostima mijenjanje veličina"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Neka sve aktivnosti budu takve da mogu mijenjati veličinu za prikaz sa više prozora, bez obzira na prikazane vrijednosti."</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"Omogući prozore nepravilnih oblika"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Omogućiti podršku za eksperimentalne prozore nepravilnih oblika."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka za rezervnu kopiju radne površine"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Potpune sigurnosne kopije za računare trenutno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da promijenite ili uklonite lozinku za potpune rezervne kopije sa radne površine"</string>
@@ -339,32 +272,24 @@
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktivno. Dodirnite za promjenu opcije."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Prikažite trenutno pokrenute usluge i upravljajte njima"</string>
-    <!-- no translation found for night_mode_title (2594133148531256513) -->
-    <skip />
+    <string name="night_mode_title" msgid="2594133148531256513">"Noćni način rada"</string>
     <string name="night_mode_summary" msgid="9196605054622017193">"%s"</string>
-    <!-- no translation found for night_mode_no (9171772244775838901) -->
-    <skip />
-    <!-- no translation found for night_mode_yes (2218157265997633432) -->
-    <skip />
+    <string name="night_mode_no" msgid="9171772244775838901">"Onemogućeno"</string>
+    <string name="night_mode_yes" msgid="2218157265997633432">"Uvijek uključeno"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatski"</string>
-    <!-- no translation found for select_webview_provider_title (4628592979751918907) -->
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
     <skip />
-    <!-- no translation found for select_webview_provider_dialog_title (4370551378720004872) -->
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
     <skip />
-    <!-- no translation found for select_webview_provider_confirmation_text (6671472080671066972) -->
-    <skip />
-    <!-- no translation found for convert_to_file_encryption (3060156730651061223) -->
-    <skip />
-    <!-- no translation found for convert_to_file_encryption_enabled (2861258671151428346) -->
-    <skip />
-    <!-- no translation found for convert_to_file_encryption_done (7859766358000523953) -->
-    <skip />
-    <!-- no translation found for title_convert_fbe (1263622876196444453) -->
-    <skip />
-    <!-- no translation found for convert_to_fbe_warning (6139067817148865527) -->
-    <skip />
-    <!-- no translation found for button_convert_fbe (5152671181309826405) -->
-    <skip />
+    <string name="select_webview_provider_title" msgid="4628592979751918907">"Postavljanje WebViewa"</string>
+    <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Podesi WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Postavljanje izabranog WebViewa je onemogućeno. Da bi se mogao koristiti, mora biti omogućen. Želite li ga omogućiti?"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"Pretvori u šifrirani fajl"</string>
+    <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Pretvaranje…"</string>
+    <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Fajl je već šifriran"</string>
+    <string name="title_convert_fbe" msgid="1263622876196444453">"Pretvaranje u šifrirane fajlove"</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Pretvori particiju sa podacima u particiju šifriranu sistemom fajlova.\n !! Upozorenje!! Ovo će izbrisati sve vaše podatke.\n Ova funkcija je u alfa fazi razvoja i možda neće ispravno raditi.\n Pritisnite \'Obriši i pretvori…\" da nastavite."</string>
+    <string name="button_convert_fbe" msgid="5152671181309826405">"Obriši i pretvori…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Režim boja Slika"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Koristi sRGB"</string>
     <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"Onemogućeno"</string>
@@ -375,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ispravka boje"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna te može utjecati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo vreme je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije"</string>
@@ -393,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Onemogućio administrator"</string>
     <string name="home" msgid="8263346537524314127">"Početna stranica"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"prije <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Još otprilike <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 333868b..beb909e 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Força permís d\'aplicacions a l\'emmagatzem. extern"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Permet que les aplicacions es puguin escriure en un dispositiu d’emmagatzematge extern, independentment dels valors definits"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Força l\'ajust de la mida de les activitats"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Permet ajustar la mida de totes les activitats per al mode multifinestra, independentment dels valors definits."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Permet ajustar la mida de totes les activitats per al mode multifinestra, independentment dels valors definits."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Activa les finestres de format lliure"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Activa la compatibilitat amb les finestres de format lliure experimentals."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Activa la compatibilitat amb finestres de format lliure experimentals."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Contrasenya per a còpies d\'ordinador"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Les còpies de seguretat d\'ordinador completes no estan protegides"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toca per canviar o suprimir la contrasenya per a les còpies de seguretat completes de l\'ordinador"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Desactivat"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Sempre activat"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automàtic"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementació de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configura la implementació de WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La implementació de WebView que has triat està desactivada i s\'ha d\'activar per utilitzar-la. Vols activar-la?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correcció del color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Aquesta funció és experimental i pot afectar el rendiment."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Temps restant aproximat: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: falten aproximadament <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Opció desactivada per l\'administrador"</string>
     <string name="home" msgid="8263346537524314127">"Inici"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Fa <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Temps restant: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index e219959..ad01feb 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Vynutit povolení aplikací na externím úložišti"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Každou aplikaci bude možné zapsat do externího úložiště, bez ohledu na hodnoty manifestu"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Vynutit možnost změny velikosti aktivit"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Velikost všech aktivit bude možné změnit na několik oken (bez ohledu na hodnoty manifestu)."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Umožnit změnu velikosti všech aktivit na několik oken (bez ohledu na hodnoty manifestu)"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Aktivovat okna s volným tvarem"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktivuje podporu experimentálních oken s volným tvarem."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktivovat podporu experimentálních oken s volným tvarem"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Heslo pro zálohy v počítači"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Úplné zálohy v počítači nejsou v současné době chráněny"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tuto možnost vyberte, chcete-li změnit nebo odebrat heslo pro úplné zálohy do počítače"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Vypnuto"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Vždy zapnuto"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatický"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementace WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Nastavte implementaci WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Vybraná implementace WebView je zakázána a nelze ji použít. Chcete ji povolit a použít?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekce barev"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkce je experimentální a může mít vliv na výkon."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g> (přibližně)"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Zakázáno administrátorem"</string>
     <string name="home" msgid="8263346537524314127">"Plocha"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"před <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Zbývající čas: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 6acdcc7..e869044 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Gennemtving tilladelse til eksternt lager"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Gør det muligt at overføre enhver app til et eksternt lager uafhængigt af manifestværdier"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Tving aktiviteter til at kunne tilpasses"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Sørger for, at alle aktiviteter kan tilpasses flere vinduer uafhængigt af manifestværdier."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Tillad, at alle aktiviteter kan tilpasses flere vinduer uafhængigt af manifestværdier."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Aktivér vinduer i frit format"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktiverer understøttelse af eksperimentelle vinduer i frit format."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktivér understøttelse af eksperimentelle vinduer i frit format."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Kode til lokal sikkerhedskopi"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Lokale fuldstændige sikkerhedskopieringer er i øjeblikket ikke beskyttet"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tryk for at skifte eller fjerne adgangskoden til fuld lokal sikkerhedskopiering"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Deaktiveret"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Altid slået til"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisk"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Konfigurer WebView-implementering"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Den valgte WebView-implementering er deaktiveret og skal aktiveres, før den kan bruges. Vil du aktivere den?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korriger farver"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funktion er eksperimentel og kan påvirke ydeevnen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> tilbage"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 5f4f60b..56d2543 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Externe Speichernutzung von Apps erlauben"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Ermöglicht es jeder qualifizierten App, Daten auf externen Speicher zu schreiben, unabhängig von den Manifestwerten"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Anpassen der Größe von Aktivitäten erzwingen"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Ermöglicht es, die Größe aller Aktivitäten an den Mehrfenstermodus anzupassen, unabhängig von den Manifestwerten."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Größe aller Aktivitäten an den Mehrfenstermodus anpassen, unabhängig von den Manifestwerten."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Freiform-Fenster zulassen"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Unterstützt experimentelle Freiform-Fenster."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Experimentelle Freiform-Fenster unterstützen."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop-Sicherungspasswort"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Vollständige Desktop-Sicherungen sind momentan nicht passwortgeschützt."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Zum Ändern oder Entfernen des Passworts für vollständige Desktop-Sicherungen tippen"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Deaktiviert"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Immer an"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisch"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-Implementierung"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-Implementierung festlegen"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Die ausgewählte WebView-Implementierung ist deaktiviert. Um sie nutzen zu können, muss sie aktiviert sein. Möchtest du sie aktivieren?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Farbkorrektur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierbei handelt es sich um eine experimentelle Funktion. Dies kann sich auf die Leistung auswirken."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Noch ca. <xliff:g id="TIME">%1$s</xliff:g> verbleibend"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch etwa <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Vom Administrator deaktiviert"</string>
     <string name="home" msgid="8263346537524314127">"Startseite"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Vor <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Noch <xliff:g id="ID_1">%1$s</xliff:g> verbleibend"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 826e823..e9f8661 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Να επιτρέπονται υποχρεωτικά εφαρμογές σε εξωτ.συσ."</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Κάνει κάθε εφαρμογή κατάλληλη για εγγραφή σε εξωτερικό χώρο αποθήκευσης, ανεξάρτητα από τις τιμές του μανιφέστου"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Αναγκαστική δυνατότητα αλλαγής μεγέθους δραστηριοτήτων"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Να έχουν όλες οι δραστηριότητες δυνατότητα αλλαγής μεγέθους για την προβολή πολλαπλών παραθύρων, ανεξάρτητα από τις τιμές του μανιφέστου."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Να έχουν όλες οι δραστηριότητες δυνατότητα αλλαγής μεγέθους για την προβολή πολλαπλών παραθύρων, ανεξάρτητα από τις τιμές του μανιφέστου."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Ενεργοποίηση παραθύρων ελεύθερης μορφής"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ενεργοποιεί την υποστήριξη για πειραματικά παράθυρα ελεύθερης μορφής."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Ενεργοποίηση υποστήριξης για πειραματικά παράθυρα ελεύθερης μορφής."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Εφ/κός κωδικός desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας δεν προστατεύονται αυτήν τη στιγμή"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Πατήστε για αλλαγή ή κατάργηση του κωδικού πρόσβασης για τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Ανενεργό"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Πάντα ενεργό"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Αυτόματο"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Υλοποίηση WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Ορισμός υλοποίησης WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Η επιλεγμένη ενσωμάτωση WebView είναι απενεργοποιημένη και θα πρέπει να ενεργοποιηθεί για να χρησιμοποιηθεί. Θέλετε να την ενεργοποιήσετε;"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Διόρθωση χρωμάτων"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Αυτή η λειτουργία είναι πειραματική και ενδεχομένως να επηρεάσει τις επιδόσεις."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Απομένουν περίπου <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Απενεργοποιήθηκε από το διαχειριστή"</string>
     <string name="home" msgid="8263346537524314127">"Αρχική οθόνη"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Πριν από <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Απομένουν <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 481cc47..668e0b2 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be re-sizable"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Makes all activities re-sizable for multi-window, regardless of manifest values."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Make all activities resizable for multi-window, regardless of manifest values."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Enable freeform windows"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Enables support for experimental freeform windows."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Enable support for experimental freeform windows."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop backup password"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Desktop full backups aren\'t currently protected"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap to change or remove the password for desktop full backups"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Disabled"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Always on"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatic"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"The chosen WebView implementation is disabled and must be enabled to be used, do you wish to enable it?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 481cc47..668e0b2 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be re-sizable"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Makes all activities re-sizable for multi-window, regardless of manifest values."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Make all activities resizable for multi-window, regardless of manifest values."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Enable freeform windows"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Enables support for experimental freeform windows."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Enable support for experimental freeform windows."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop backup password"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Desktop full backups aren\'t currently protected"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap to change or remove the password for desktop full backups"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Disabled"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Always on"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatic"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"The chosen WebView implementation is disabled and must be enabled to be used, do you wish to enable it?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 481cc47..668e0b2 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be re-sizable"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Makes all activities re-sizable for multi-window, regardless of manifest values."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Make all activities resizable for multi-window, regardless of manifest values."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Enable freeform windows"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Enables support for experimental freeform windows."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Enable support for experimental freeform windows."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop backup password"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Desktop full backups aren\'t currently protected"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap to change or remove the password for desktop full backups"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Disabled"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Always on"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatic"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"The chosen WebView implementation is disabled and must be enabled to be used, do you wish to enable it?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 7380240..05ab073 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forzar permisos en almacenamiento externo"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Cualquier aplicación puede escribirse en una memoria externa, independientemente de los valores del manifiesto."</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forzar actividades para que cambien de tamaño"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Permite que todas las actividades puedan cambiar de tamaño para el modo multiventana, sin importar los valores del manifiesto."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Permitir que todas las actividades puedan cambiar de tamaño para el modo multiventana, sin importar los valores del manifiesto."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Habilitar ventanas de forma libre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Habilita la admisión de ventanas de forma libre experimentales."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Habilitar la admisión de ventanas de forma libre experimentales."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Contraseñas"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Tus copias de seguridad de escritorio no están protegidas por contraseña."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Presiona para cambiar o quitar la contraseña de las copias de seguridad completas de tu escritorio."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Inhabilitado"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Siempre activado"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementación de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configurar la implementación de WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La implementación de WebView que elegiste está inhabilitada. Debes habilitarla para poder usarla. ¿Quieres hacerlo?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección de color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar el rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Falta <xliff:g id="TIME">%1$s</xliff:g> aproximadamente"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: alrededor de <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Inhabilitada por el administrador"</string>
     <string name="home" msgid="8263346537524314127">"Página principal"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Hace <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Falta <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1cf51fe..5fea7554 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forzar permiso de aplicaciones de forma externa"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Hace que cualquier aplicación se pueda escribir en un dispositivo de almacenamiento externo, independientemente de los valores definidos"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forzar el ajuste de tamaño de las actividades"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Permite que se pueda ajustar el tamaño de todas las actividades para el modo multiventana, independientemente de los valores establecidos."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Permite que se pueda ajustar el tamaño de todas las actividades para el modo multiventana, independientemente de los valores establecidos."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Habilitar ventanas de forma libre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Permite utilizar ventanas de forma libre experimentales."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Habilita la opción para utilizar ventanas de forma libre experimentales."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Contraseña para copias de ordenador"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Las copias de seguridad completas de ordenador no están protegidas"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toca para cambiar o quitar la contraseña de las copias de seguridad completas del escritorio"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Inhabilitado"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Siempre activado"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementación de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Establecer implementación de WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La implementación de WebView seleccionada está inhabilitada y debes habilitarla para utilizarla. ¿Quieres hacerlo?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección del color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar al rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Tiempo restante (aproximado): <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quedan <xliff:g id="TIME">%2$s</xliff:g> aproximadamente"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Inhabilitada por el administrador"</string>
     <string name="home" msgid="8263346537524314127">"Inicio"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Hace <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Tiempo restante: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index c5153ff..b9d011b 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Luba rakendused välises salvestusruumis"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Lubab rakendusi kirjutada välisesse salvestusruumi olenemata manifesti väärtustest"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Muuda tegevuste suurused muudetavaks"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Muudab kõigi tegevuste suurused mitme aknaga vaates olenemata manifesti väärtustest muudetavaks."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Muudetakse kõigi tegevuste suurused mitme aknaga vaates muudetavaks (manifesti väärtustest olenemata)."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Luba vabas vormis aknad"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Lubatakse katseliste vabas vormis akende tugi."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Lubatakse katseliste vabavormis akende tugi."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Arvutivarunduse parool"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Täielikud arvutivarundused pole praegu kaitstud"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Puudutage täielike arvutivarunduste parooli muutmiseks või eemaldamiseks"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Keelatud"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Alati sees"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automaatne"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView\' rakendamine"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView\' rakendamise seadistamine"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Valitud WebView\' rakendamisviis on keelatud ja see tuleb kasutamiseks lubada. Kas soovite selle lubada?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värviparandus"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"See funktsioon on katseline ja võib mõjutada toimivust."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Umbes <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Umbes <xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – jäänud on umbes <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis"</string>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 1e06c6a..c1be37f 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Behartu aplikazioak onartzea kanpoko biltegian"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Aplikazioek kanpoko memorian idatz dezakete, manifestuaren balioak kontuan izan gabe"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Behartu jardueren tamaina doitu ahal izatea"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Manifestuan jartzen duena jartzen duela ere, jarduera guztien tamaina doitzeko aukera ematen du, hainbat leihotan erabili ahal izan daitezen."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Eman aukera jarduera guztien tamaina doitzeko, hainbat leihotan erabili ahal izan daitezen, manifestuan jartzen duena jartzen duela ere."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Gaitu estilo libreko leihoak"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Estilo libreko leiho esperimentalak onartzen ditu."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Onartu estilo libreko leiho esperimentalak."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Tokiko babeskop. pasahitza"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Une honetan, ordenagailuko babeskopia osoak ez daude babestuta."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ordenagailuko eduki guztiaren babeskopia egiteko erabiltzen den pasahitza aldatzeko edo kentzeko, sakatu hau"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Desgaituta"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Beti aktibatuta"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatikoa"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Desgaituta dago aukeratu den WebView inplementazioa. Erabili nahi izanez gero, gaitu egin behar duzu. Gaitu nahi al duzu?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kolore-zuzenketa"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> inguru guztiz kargatu arte"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> inguru. <xliff:g id="TIME">%2$s</xliff:g> geratzen d(ir)a"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Administratzaileak desgaitu du"</string>
     <string name="home" msgid="8263346537524314127">"Hasierako pantaila"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Duela <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> guztiz kargatu arte"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index e023f247..fc4cd7d 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"اجازه اجباری به برنامه‌های دستگاه ذخیره خارجی"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"بدون توجه به مقادیر مانیفست، هر برنامه‌ای را برای نوشتن در حافظه خارجی واجد شرایط می‌کند"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"اجبار فعالیت‌ها به قابل تغییر اندازه بودن"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"بدون درنظر گرفتن مقادیر مانیفست، همه فعالیت‌ها را برای چندپنجره قابل تغییر اندازه می‌کند."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"بدون توجه به مقادیر مانیفست، اندازه همه فعالیت‌ها برای حالت چند پنجره‌ای می‌تواند تغییر کند."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"فعال کردن پنجره‌های آزاد"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"پشتیبانی برای پنجره‌های آزاد آزمایشی را امکان‌پذیر می‌کند"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"فعال کردن پشتیبانی برای پنجره‌های آزاد آزمایشی."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"گذرواژه پشتیبان‌گیری محلی"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"پشتیبان‌گیری کامل رایانه درحال حاضر محافظت نمی‌شود"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"برای تغییر یا حذف گذرواژه برای نسخه‌های پشتیبان کامل رایانه‌ای ضربه بزنید"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"غیرفعال است"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"همیشه روشن"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"خودکار"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"‏اجرای WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"‏تنظیم اجرای WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"‏پیاده‌سازی WebView انتخاب‌شده غیرفعال شده است و برای استفاده شدن باید فعال شود؛ می‌خواهید آن را فعال کنید؟"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحیح رنگ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"این قابلیت آزمایشی است و ممکن است عملکرد را تحت تأثیر قرار دهد."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> باقی مانده است"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً ‏<xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"سرپرست آن را غیرفعال کرده است"</string>
     <string name="home" msgid="8263346537524314127">"صفحه اصلی"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> قبل"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> باقی مانده است"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index c4f572c..34309c1 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Salli aina ulkoinen tallennus"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Mahdollistaa sovellusten tallentamisen ulkoiseen tall.tilaan luettelosta riippumatta"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Pakota kaikki toiminnot hyväksymään koon muutos"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Pakottaa kaikki toiminnot hyväksymään koon muuttamisen rinnakkaisnäkymään luettelon arvoista riippumatta."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Pakota kaikki toiminnot hyväksymään koon muuttaminen usean ikkunan tilassa luettelon arvoista riippumatta."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Ota käyttöön vapaamuotoiset ikkunat"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ottaa käyttöön kokeellisten vapaamuotoisten ikkunoiden tuen."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Ota kokeellisten vapaamuotoisten ikkunoiden tuki käyttöön."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Varmuuskop. salasana"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Tietokoneen kaikkien tietojen varmuuskopiointia ei ole tällä hetkellä suojattu"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Vaihda tai poista tietokoneen kaikkien tietojen varmuuskopioinnin salasana koskettamalla."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Ei käytössä"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Aina käytössä"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automaattinen"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-käyttöönotto"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Määritä WebView-käyttöönotto"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Valittu WebView-käyttöönotto on poistettu käytöstä. Haluatko ottaa sen käyttöön?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värikorjaus"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tämä ominaisuus on kokeellinen ja voi vaikuttaa suorituskykyyn."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Järjestelmänvalvojan käytöstä poistama"</string>
     <string name="home" msgid="8263346537524314127">"Aloitusnäyttö"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> sitten"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> jäljellä"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index f888ec8..1181c2a3 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forcer l\'autor. d\'applis sur stockage externe"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Permet enreg. d\'applis sur espace stockage externe"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forcer les activités à être redimensionnables"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Permet de redimensionner toutes les activités pour le mode multifenêtre, indépendamment des valeurs du fichier manifeste."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Permet de redimensionner toutes les activités pour le mode multifenêtre, indépendamment des valeurs du fichier manifeste."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Activer les fenêtres de forme libre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Active la compatibilité avec les fenêtres de forme libre expérimentales."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Activer la compatibilité avec les fenêtres de forme libre expérimentales."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Mot de passe sauvegarde PC"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Les sauvegardes complètes sur PC ne sont pas protégées actuellement."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Touchez pour modifier ou supprimer le mot de passe utilisé pour les sauvegardes complètes sur ordinateur."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Désactivé"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Toujours actif"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatique"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Mise en œuvre WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Définir la mise en œuvre WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La mise en œuvre WebView sélectionnée est désactivée. Vous devez l\'activer pour l\'utiliser. Souhaitez-vous l\'activer?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction des couleurs"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut toucher les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> %% – Temps restant : environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Désactivé par l\'administrateur"</string>
     <string name="home" msgid="8263346537524314127">"Accueil"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Il y a <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Durée restante :<xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index dfc71f1..0639f1f 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forcer disponibilité stockage externe pour applis"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Rend possible enregistrement de toute appli sur espace stockage externe, indépendamment valeurs fichier manifeste."</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forcer possibilité de redimensionner les activités"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Permet de redimensionner toutes les activités pour le mode multifenêtre, indépendamment des valeurs du fichier manifeste."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Permettre de redimensionner toutes les activités pour le mode multifenêtre, indépendamment des valeurs du fichier manifeste."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Activer les fenêtres de forme libre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Active la compatibilité avec les fenêtres de forme libre expérimentales."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Activer la compatibilité avec les fenêtres de forme libre expérimentales."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Mot de passe sauvegarde PC"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Les sauvegardes complètes sur PC ne sont pas protégées actuellement."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Appuyez pour modifier ou supprimer le mot de passe utilisé pour les sauvegardes complètes sur PC."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Désactivé"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Toujours activé"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatique"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Mise en œuvre WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Définir la mise en œuvre WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La mise en œuvre WebView sélectionnée est désactivée. Vous devez l\'activer pour l\'utiliser. Souhaitez-vous l\'activer ?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction couleur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>."</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g> environ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Désactivé par l\'administrateur"</string>
     <string name="home" msgid="8263346537524314127">"Accueil"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Il y a <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Il reste <xliff:g id="ID_1">%1$s</xliff:g>."</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index 20985bd..5622d63 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forzar permiso de aplicacións de forma externa"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Fai que calquera aplicación se poida escribir nun almacenamento externo, independentemente dos valores expresados"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forzar o axuste do tamaño das actividades"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Permite axustar o tamaño de todas as actividades para o modo de varias ventás, independentemente dos valores definidos."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Permite axustar o tamaño de todas as actividades para o modo de varias ventás, independentemente dos valores definidos."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Activar ventás de forma libre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Activa a compatibilidade con ventás de forma libre experimentais."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Activa a compatibilidade con ventás de forma libre experimentais."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Contrasinal para copias"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"As copias de seguridade de ordenador completas non están protexidas"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toca para cambiar ou eliminar o contrasinal para as copias de seguranza completas do escritorio"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Desactivado"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Sempre activada"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementación de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Definir implementación de WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementación de WebView escollida está desactivada e, para poder usala, debe estar activada. Queres activala?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función é experimental e pode afectar ao rendemento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Duración aproximada de <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - faltan aproximadamente <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Desactivado polo administrador"</string>
     <string name="home" msgid="8263346537524314127">"Inicio"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Hai <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Tempo restante: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 18917e0..2c1990f 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"બાહ્ય પર એપ્લિકેશનોને મંજૂરી આપવાની ફરજ પાડો"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"મેનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, કોઈપણ એપ્લિકેશનને બાહ્ય સ્ટોરેજ પર લખાવા માટે લાયક બનાવે છે"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"પ્રવૃત્તિઓને ફરીથી કદ યોગ્ય થવા માટે ફરજ પાડો"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"તમામ પ્રવૃત્તિઓને મલ્ટી-વિંડો માટે ફરીથી કદ બદલી શકે તેવી બનાવે છે, મેનીફેસ્ટ મુલ્યોને ધ્યાનમાં લીધા સિવાય."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"મૅનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, તમામ પ્રવૃત્તિઓને મલ્ટી-વિંડો માટે ફરીથી કદ બદલી શકે તેવી બનાવો."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"ફ્રિફોર્મ વિંડોઝ સક્ષમ કરો"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"પ્રાયોગિક ફ્રિફોર્મ વિંડોઝ માટે સમર્થનને સક્ષમ કરે છે."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"પ્રાયોગિક ફ્રિફોર્મ વિંડોઝ માટે સમર્થનને સક્ષમ કરો."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ડેસ્કટૉપ બેકઅપ પાસવર્ડ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ડેસ્કટૉપ સંપૂર્ણ બેકઅપ હાલમાં સુરક્ષિત નથી"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ડેસ્કટૉપ સંપૂર્ણ બેકઅપ્સ માટેનો પાસવર્ડ બદલવા અથવા દૂર કરવા માટે ટૅચ કરો"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"અક્ષમ કરેલ"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"હંમેશાં ચાલુ"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"સ્વચલિત"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView અમલીકરણ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView અમલીકરણ સેટ કરો"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"પસંદ કરેલ WebView અમલીકરણ અક્ષમ કરેલ છે અને ઉપયોગ કરવા માટે સક્ષમ કરવું આવશ્યક છે, શું તમે તેને સક્ષમ કરવા માગો છો?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"રંગ સુધારણા"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"આ સુવિધા પ્રાયોગિક છે અને કામગીરી પર અસર કરી શકે છે."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"અંદાજે. <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - આશરે <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"સંપૂર્ણ થવામાં <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"વ્યવસ્થાપક દ્વારા અક્ષમ"</string>
     <string name="home" msgid="8263346537524314127">"હોમ"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> પહેલાં"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> બાકી"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 32b2814..7deb05c 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"ऐप्स को बाहरी मेमोरी पर बाध्‍य करें"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"इससे कोई भी ऐप मेनिफेस्‍ट मान अनदेखा करके, बाहरी मेमोरी पर लिखने योग्‍य बन जाता है"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"आकार बदले जाने के लिए गतिविधियों को बाध्य करें"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"एकाधिक-विंडो के लिए सभी गतिविधियों के आकार को बदले जाने योग्य बनाता है, चाहे मेनिफेस्ट मान कुछ भी हों."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"सभी गतिविधियों को एकाधिक विंडो के लिए आकार बदलने योग्य बनाएं, चाहे मेनिफेस्ट मान कुछ भी हों."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"फ़्रीफ़ॉर्म विंडो सक्षम करें"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"प्रयोगात्मक फ़्रीफ़ॉर्म विंडो का समर्थन सक्षम करती है."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"प्रयोगात्मक फ़्रीफ़ॉर्म विंडो का समर्थन सक्षम करें."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"डेस्‍कटॉप बैकअप पासवर्ड"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"डेस्‍कटॉप पूर्ण बैकअप वर्तमान में सुरक्षित नहीं हैं"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"डेस्कटॉप के पूर्ण बैकअप का पासवर्ड बदलने या निकालने के लिए टैप करें"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"अक्षम"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"हमेशा चालू"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"स्वचालित"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView कार्यान्वयन"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView कार्यान्वयन सेट करें"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"चुना गया WebView कार्यान्वयन अक्षम है और उसे उपयोग करने के लिए सक्षम किया जाना आवश्यक है, क्या आप उसे सक्षम करना चाहते हैं?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यह सुविधा प्रायोगिक है और निष्पादन को प्रभावित कर सकती है."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी होने तक"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 37b5363..ca58584 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Prisilno dopusti aplikacije u vanjskoj pohrani"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Aplikacije se mogu zapisivati u vanjsku pohranu neovisno o manifestu"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Nametni mogućnost promjene veličine za aktivnosti"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Veličina svih aktivnosti može se mijenjati za više prozora, neovisno o vrijednostima manifesta."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Omogući mijenjanje veličine svih aktivnosti za više prozora, neovisno o vrijednostima manifesta."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Omogući prozore slobodnog oblika"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Omogućuje podršku za eksperimentalne prozore slobodnog oblika."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Omogući podršku za eksperimentalne prozore slobodnog oblika."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Zaporka sigurnosne kopije"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Potpune sigurnosne kopije na stolnom računalu trenutačno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da biste promijenili ili uklonili zaporku za potpune sigurnosne kopije na računalu"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Onemogućeno"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Uvijek uključeno"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatska"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementacija WebViewa"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Postavi implementaciju WebViewa"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Odabrana implementacija WebViewa onemogućena je i morate je omogućiti da biste je mogli upotrebljavati. Želite li je omogućiti?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boje"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova je značajka eksperimentalna i može utjecati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – još približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 9113ab3..365c409 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Külső tárhely alkalmazásainak engedélyezése"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Lehetővé teszi, hogy külső tárhelyre lehessen írni"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Tevékenységek átméretezésének kényszerítése"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Lehetővé teszi, hogy az összes tevékenység átméretezhető legyen a többablakos megjelenítés érdekében a jegyzékértékektől függetlenül."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Legyen az összes tevékenység átméretezhető a többablakos megjelenítés érdekében a jegyzékértékektől függetlenül."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Szabad formájú ablakok engedélyezése"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Engedélyezi a kísérleti jellegű, szabad formájú ablakok támogatását."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Kísérleti, szabad formájú ablakok támogatásának engedélyezése."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Asztali mentés jelszava"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Az asztali teljes biztonsági mentések jelenleg nem védettek."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Koppintson ide az asztali teljes mentések jelszavának módosításához vagy eltávolításához"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Kikapcsolva"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Mindig bekapcsolva"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatikus"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-megvalósítás"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-megvalósítás beállítása"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A kiválasztott WebView-megvalósítás le van tiltva, a használathoz viszont engedélyezni kell. Szeretné engedélyezni?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Színkorrekció"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ez egy kísérleti funkció, és hatással lehet a teljesítményre."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kb. <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kb. <xliff:g id="TIME">%1$s</xliff:g> van hátra"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – kb. <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes töltöttség eléréséig"</string>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index 2baa160..b210698 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Միշտ թույլատրել ծրագրեր արտաքին պահեստում"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Թույլ է տալիս պահել հավելվածը արտաքին սարքում՝ մանիֆեստի արժեքներից անկախ"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Ստիպել, որ ակտիվությունների չափերը լինեն փոփոխելի"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Բոլոր ակտիվությունների չափերը բազմապատուհան ռեժիմի համար դարձնել փոփոխելի՝ մանիֆեստի արժեքներից անկախ:"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Բոլոր ակտիվությունների չափերը բազմապատուհան ռեժիմի համար դարձնել փոփոխելի՝ մանիֆեստի արժեքներից անկախ:"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Ակտիվացնել կամայական ձևի պատուհանները"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ակտիվացնում է կամայական ձևի փորձնական պատուհանների աջակցումը:"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Միացնել ազատ ձևի փորձնական պատուհանների աջակցումը:"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Աշխատասեղանի պահուստավորման գաղտնաբառ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Աշխատասեղանի ամբողջական պահուստավորումները այժմ պաշտպանված չեն"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Հպեք՝ աշխատասեղանի ամբողջական պահուստավորման գաղտնաբառը փոխելու կամ հեռացնելու համար"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Անջատված"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Միշտ միացված"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Ավտոմատ"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-ի իրականացում"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Ընտրեք WebView-ի իրականացումը"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"WebView-ի իրականացման ընտրված եղանակն անջատված է և օգտագործելու համար պետք է նախ միացվի: Միացնե՞լ:"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Գունային կարգաբերում"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Սա փորձնական գործառույթ է և կարող է ազդել աշխատանքի վրա:"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնաց մոտավորապես <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Կասեցված է ադմինիստրատորի կողմից"</string>
     <string name="home" msgid="8263346537524314127">"Գլխավոր էջ"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> առաջ"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Մնացել է <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 1a47576..33e869c 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Paksa izinkan aplikasi di eksternal"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Membuat semua aplikasi dapat ditulis ke penyimpanan eksterna"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Paksa aktivitas agar ukurannya dapat diubah"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Membuat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Buat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Aktifkan jendela berformat bebas"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Mengaktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Sandi cadangan desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Saat ini cadangan desktop penuh tidak dilindungi"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Dinonaktifkan"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Selalu aktif"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Otomatis"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Penerapan WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Setel penerapan WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Implementasi WebView yang dipilih telah dinonaktifkan, dan harus diaktifkan agar dapat digunakan. Ingin mengaktifkannya?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Koreksi warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Fitur ini bersifat eksperimental dan dapat memengaruhi kinerja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira tersisa <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira tersisa. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Dinonaktifkan oleh administrator"</string>
     <string name="home" msgid="8263346537524314127">"Layar Utama"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> lalu"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Tersisa <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 558f7bc..b79dcf8 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Þvinga fram leyfi forrita í ytri geymslu"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Gerir hvaða forriti sem er kleift að skrifa í ytri geymslu, burtséð frá gildum í upplýsingaskrá"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Þvinga breytanlega stærð virkni"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Gerir stærð allrar virkni breytanlega svo að hún henti fyrir marga glugga, óháð gildum í upplýsingaskrá."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Gera stærð allrar virkni breytanlega svo að hún henti fyrir marga glugga, óháð gildum í upplýsingaskrá."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Virkja glugga með frjálsu sniði"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Kveikir á stuðningi við glugga með frjálsu sniði á tilraunastigi."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Virkja stuðning við glugga með frjálsu sniði á tilraunastigi."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Aðgangsorð tölvuafritunar"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Heildarafritun á tölvu er ekki varin sem stendur."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ýttu til að breyta eða fjarlægja aðgangsorðið fyrir heildarafritun á tölvu"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Óvirkt"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Alltaf kveikt"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Sjálfvirkt"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Innleiðing WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Stilla innleiðingu WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Slökkt er á valinni innleiðingu WebView. Kveikja þarf á henni til að hægt sé að nota hana. Viltu gera það?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Litaleiðrétting"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Þessi eiginleiki er á tilraunastigi og getur haft áhrif á frammistöðu."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Um það bil <xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – u.þ.b. <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Stjórnandi gerði óvirkt"</string>
     <string name="home" msgid="8263346537524314127">"Heim"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Fyrir <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> eftir"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 24564c1..d5753c4 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forza autorizzazione app su memoria esterna"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Rende l\'app idonea all\'installaz. su mem. esterna, senza considerare i valori manifest"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Imponi formato modificabile alle attività"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Rende il formato di tutte le attività modificabile per la modalità multi-finestra, indipendentemente dai valori manifest."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Rendi il formato di tutte le attività modificabile per la modalità multi-finestra, indipendentemente dai valori manifest."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Attiva finestre a forma libera"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Attiva il supporto per le finestre a forma libera sperimentali."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Attiva il supporto delle finestre a forma libera sperimentali."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Password di backup desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"I backup desktop completi non sono attualmente protetti."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tocca per modificare o rimuovere la password per i backup desktop completi"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Disattivato"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Sempre attivo"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatico"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementazione di WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Imposta l\'implementazione di WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"L\'implementazione di WebView selezionata non è attiva e deve essere attivata per poterla utilizzare. Vuoi attivarla?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correzione del colore"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Circa <xliff:g id="TIME">%1$s</xliff:g> rimanenti"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g> circa"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Disattivata dall\'amministratore"</string>
     <string name="home" msgid="8263346537524314127">"Home page"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> fa"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> rimanenti"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 5dea0a2..ee2588f 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"אילוץ הרשאה של אפליקציות באחסון חיצוני"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"מאפשר כתיבה של כל אפליקציה באחסון חיצוני, ללא התחשבות בערכי המניפסט"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"אלץ יכולת קביעת גודל של הפעילויות"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"מאפשר יכולת קביעת גודל של כל הפעילויות לריבוי חלונות, ללא קשר לערך המניפסט."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"אפשר יכולת קביעת גודל של כל הפעילויות לריבוי חלונות, ללא קשר לערך המניפסט."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"הפעל את האפשרות לשנות את הגודל והמיקום של החלונות"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"מפעיל תמיכה בתכונה הניסיונית של שינוי הגודל והמיקום של החלונות."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"הפעל תמיכה בתכונה הניסיונית של שינוי הגודל והמיקום של החלונות."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"סיסמת גיבוי מקומי"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"גיבויים מלאים בשולחן העבודה אינם מוגנים כעת"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"הקש כדי לשנות או להסיר את הסיסמה לגיבויים מלאים בשולחן העבודה"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"מושבת"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"פועל תמיד"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"באופן אוטומטי"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"‏יישום WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"‏הגדרת יישום WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"‏יישום ה-WebView שנבחר מושבת, ויש להפעיל אותו כדי להשתמש בו. האם ברצונך להפעיל אותו?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"תיקון צבע"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"תכונה זו היא ניסיונית ועשויה להשפיע על הביצועים."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"נשארו <xliff:g id="TIME">%1$s</xliff:g> בערך"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> בקירוב עד לסיום"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>‏ - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> ‏- <xliff:g id="TIME">%2$s</xliff:g> עד למילוי"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"הושבת על ידי מנהל המערכת"</string>
     <string name="home" msgid="8263346537524314127">"דף הבית"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"לפני <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"נשארו <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index eb7f8af..67bf4b0 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"外部ストレージへのアプリの書き込みを許可"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"マニフェストの値に関係なく、すべてのアプリを外部ストレージに書き込めるようになります"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"アクティビティをサイズ変更可能にする"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"マニフェストの値に関係なく、マルチウィンドウですべてのアクティビティのサイズを変更できるようになります。"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"マニフェストの値に関係なく、マルチウィンドウですべてのアクティビティのサイズを変更できるようにします。"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"フリーフォーム ウィンドウの有効化"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"テスト段階のフリーフォーム ウィンドウのサポートを有効にします。"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"外部のフリーフォーム ウィンドウのサポートを有効にします。"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"PCバックアップパスワード"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"デスクトップのフルバックアップは現在保護されていません"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"デスクトップのフルバックアップ用のパスワードを変更または削除する場合にタップします"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"無効"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"常にON"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"自動"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView の実装"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView の実装の設定"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"選択した WebView の実装は無効になっていますが、使用するには有効にする必要があります。有効にしますか?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色補正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"この機能は試験運用機能であり、パフォーマンスに影響することがあります。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"あと約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -316,8 +319,6 @@
     <skip />
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"管理者によって無効にされています"</string>
     <string name="home" msgid="8263346537524314127">"ホーム"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"あと <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 540dc81..f441fa0 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"აპების დაშვება გარე მეხსიერებაში"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"აპები ჩაიწერ. გარე მეხს.-ზე აღწ. ფაილის მნიშვნ. მიუხედ."</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"ზომაცვლადი აქტივობების იძულება"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"მანიფესტის მნიშვნელობების მიუხედავად, ყველა აქტივობას მრავალი ფანჯრის რეჟიმისთვის ზომაცვლადად აქცევს."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"მანიფესტის მნიშვნელობების მიუხედავად, მრავალი ფანჯრის რეჟიმისთვის ყველა აქტივობის ზომაცვლადად გადაქცევა."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"თავისუფალი ფორმის მქონე ფანჯრების ჩართვა"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"ჩართავს თავისუფალი ფორმის მქონე ფანჯრების მხარდაჭერის ექსპერიმენტულ ფუნქციას"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"თავისუფალი ფორმის მქონე ფანჯრების მხარდაჭერის ექსპერიმენტული ფუნქციის ჩართვა."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"დესკტოპის სარეზერვო ასლის პაროლი"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"დესკტოპის სრული სარეზერვო ასლები ამჟამად დაცული არ არის"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"შეეხეთ დესკტოპის სრული სარეზერვო ასლების პაროლის შესაცვლელად ან წასაშლელად"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"გამორთულია"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"ყოველთვის ჩართული"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ავტომატური"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView რეალიზაცია"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView რეალიზაციის დაყენება"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"არჩეული WebView რეალიზაცია გათიშულია და გამოყენებამდე უნდა ჩაირთოს. გსურთ მისი ჩართვა?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ფერის კორექცია"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ეს ფუნქცია საცდელია და შეიძლება გავლენა იქონიოს შესრულებაზე."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"დარჩენილია დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"დაახლ. <xliff:g id="LEVEL">%1$s</xliff:g> დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> სრულ დატენვამდე"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"გათიშულია ადმინისტრატორის მიერ"</string>
     <string name="home" msgid="8263346537524314127">"მთავარი"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"გავიდა <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"დარჩენილია <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index 7f59d97..fb5ab12 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Сыртқыда қолданбаларға мәжбүрлеп рұқсат ету"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Манифест мәндеріне қарамастан кез келген қолданбаны сыртқы жадқа жазуға жарамды етеді"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Әрекеттерді өлшемін өзгертуге болатын етуге мәжбүрлеу"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Манифест мәндеріне қарамастан барлық әрекеттерді бірнеше терезе үшін өлшемін өзгертуге болатын етеді."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Манифест мәндеріне қарамастан барлық әрекеттерді бірнеше терезе үшін өлшемін өзгертуге болатын етеді."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Еркін пішіндегі терезелерді қосу"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Эксперименттік еркін пішіндегі терезелерді қолдауды қосады."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Эксперименттік еркін терезелерді қолдауды қосу."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Компьютер үстелінің сақтық көшірмесі"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Жұмыс үстелінің сақтық көшірмелері қазір қорғалмаған"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Үстелдік компьютердің толық сақтық көшірмелерінің кілтсөзін өзгерту немесе жою үшін түртіңіз"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Өшірілген"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Әрқашан қосулы"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Aвтоматты"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ендіру"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView ендіруін орнату"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Таңдалған веб-көріністі енгізу өшірілген және пайдалану үшін оны қосу керек. Оны қосу керек пе?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсті түзету"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бұл мүмкіндік эксперименттік болып табылады және өнімділікке әсер етуі мүмкін."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Әкімші өшірген"</string>
     <string name="home" msgid="8263346537524314127">"Негізгі бет"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> бұрын"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> қалды"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index a949538..c1946c4 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"បង្ខំឲ្យអនុញ្ញាតកម្មវិធីលើឧបករណ៍ផ្ទុកខាងក្រៅ"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ធ្វើឲ្យកម្មវិធីទាំងឡាយមានសិទ្ធិសរសេរទៅកាន់ឧបករណ៍ផ្ទុកខាងក្រៅ ដោយមិនគិតពីតម្លៃជាក់លាក់"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"បង្ខំឲ្យសកម្មភាពអាចប្តូរទំហំបាន"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"កំណត់ឲ្យសកម្មភាពទាំងអស់អាចប្តូរទំហំបានសម្រាប់ពហុផ្ទាំងវិនដូ ដោយមិនគិតពីតម្លៃមេនីហ្វេសឡើយ។"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"កំណត់ឲ្យសកម្មភាពទាំងអស់អាចប្តូរទំហំបានសម្រាប់ពហុផ្ទាំងវិនដូ ដោយមិនគិតពីតម្លៃមេនីហ្វេស។"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"បើកដំណើរការផ្ទាំងវិនដូទម្រង់សេរី"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"បើកដំណើរការគាំទ្រផ្ទាំងវិនដូទម្រង់សេរីសាកល្បង"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"បើកដំណើរការគាំទ្រផ្ទាំងវិនដូទម្រង់សេរីសាកល្បង"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ពាក្យ​សម្ងាត់​បម្រុង​ទុក​លើ​ផ្ទៃតុ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ការ​បម្រុង​ទុក​ពេញលេញ​លើ​ផ្ទៃតុ​បច្ចុប្បន្ន​មិន​ត្រូវ​បាន​ការពារ​ទេ។"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ប៉ះដើម្បីប្ដូរ ឬយកពាក្យសម្ងាត់ចេញសម្រាប់ការបម្រុងទុកពេញលេញលើកុំព្យូទ័រ"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"បានបិទ"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"បើកជានិច្ច"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ស្វ័យប្រវត្តិ"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"ការប្រតិបត្តិ WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"កំណត់ការប្រតិបត្តិ WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"ការប្រតិបត្តិការ WebView ដែលបានជ្រើសត្រូវបានបិទដំណើរការ ប៉ុន្តែអ្នកត្រូវបើកដំណើរការវាដើម្បីប្រើ តើអ្នកចង់បើកដំណើរការវាដែរឬទេ?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ការ​កែ​ពណ៌"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"លក្ខណៈ​នេះ​គឺ​ជា​ការ​ពិសោធន៍ ហើយ​អាច​ប៉ះពាល់​ការ​អនុវត្ត។"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"នៅសល់ប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅ​សល់​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូត​ដល់​ពេញ"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រង"</string>
     <string name="home" msgid="8263346537524314127">"ដើម"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> មុន"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"នៅសល់ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index bfe0c1e..a6acd17 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"ಬಾಹ್ಯವಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಒತ್ತಾಯವಾಗಿ ಅನುಮತಿಸಿ"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಪರಿಗಣಿಸದೇ, ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಒತ್ತಾಯ ಮಾಡಿ"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಪರಿಗಣಿಸದೇ, ಬಹು-ವಿಂಡೊಗೆ ಎಲ್ಲಾ ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಮಾಡುತ್ತದೆ."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಪರಿಗಣಿಸದೇ, ಬಹು-ವಿಂಡೊಗೆ ಎಲ್ಲಾ ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಮಾಡಿ."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"ಮುಕ್ತಸ್ವರೂಪದ ವಿಂಡೊಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"ಪ್ರಾಯೋಗಿಕ ಮುಕ್ತಸ್ವರೂಪದ ವಿಂಡೊಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ಪ್ರಾಯೋಗಿಕ ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೊಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ಡೆಸ್ಕ್‌ಟಾಪ್ ಬ್ಯಾಕಪ್ ಪಾಸ್‌ವರ್ಡ್"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ಡೆಸ್ಕ್‌ಟಾಪ್‌‌ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌‌ಗಳನ್ನು ಪ್ರಸ್ತುತ ರಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ಡೆಸ್ಕ್‌ಟಾಪ್‌ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌ಗಳಿಗೆ ಪಾಸ್‌ವರ್ಡ್‌ ಬದಲಾಯಿಸಲು ಅಥವಾ ತೆಗೆದುಹಾಕಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"ಯಾವಾಗಲೂ ಆನ್"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ಸ್ವಯಂಚಾಲಿತ"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ಅನುಷ್ಠಾನಗೊಳಿಸುವಿಕೆ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView ಅನುಷ್ಠಾನಗೊಳಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"ಆಯ್ಕೆಮಾಡಲಾದ WebView ಅನುಷ್ಠಾನಗೊಳಿಸುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಮತ್ತು ಬಳಸಲು ಸಕ್ರಿಯಗೊಳಿಸಬೇಕಾಗಿದೆ, ಇದನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ನೀವು ಬಯಸುತ್ತೀರಾ?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ಬಣ್ಣದ ತಿದ್ದುಪಡಿ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ಇದು ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಕಾರ್ಯಕ್ಷಮತೆ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ಸುಮಾರು <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"ಸುಮಾರು <xliff:g id="LEVEL">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 5d1176a..c8bb2e6 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"외부에서 앱 강제 허용"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"매니페스트 값에 관계없이 앱을 외부 저장소에 작성"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"활동의 크기가 조정 가능하도록 설정"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"모든 활동을 매니페스트 값에 관계없이 멀티 윈도우용으로 크기 조정 가능하도록 설정"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"모든 활동을 매니페스트 값에 관계없이 멀티 윈도우용으로 크기 조정 가능하도록 설정"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"자유 형식 창 사용"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"자유 형식 창(베타) 지원 사용"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"자유 형식 창 지원 사용"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"데스크톱 백업 비밀번호"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"데스크톱 전체 백업에 비밀번호가 설정되어 있지 않음"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"데스크톱 전체 백업에 대한 비밀번호를 변경하거나 삭제하려면 탭하세요."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"사용 안함"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"항상 사용"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"자동"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView 구현"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView 구현 설정"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"선택한 WebView 구현이 사용 중지되어 있습니다. 사용하려면 사용 설정해야 합니다. 사용 설정하시겠습니까?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"색보정"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"실험실 기능이며 성능에 영향을 줄 수 있습니다."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 대략 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"관리자가 사용 중지함"</string>
     <string name="home" msgid="8263346537524314127">"홈"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> 전"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> 남음"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index f0867f5..6f158c0 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Тышкы сактагычка сактоого уруксат берүү"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Манифест маанилерине карабастан бардык колдонмолорду тышкы сактагычка сактоого уруксат берет"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Аракеттердин өлчөмүн өзгөртүүнү мажбурлоо"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Манифест маанилерине карабастан бардык аракеттерди мульти-терезеге өлчөмү өзгөртүлгүдөй кылат."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Манифест маанилерине карабастан бардык аракеттерди мульти-терезеге өлчөмү өзгөртүлгүдөй кылуу."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Эркин формадагы терезелерди түзүүнү иштетүү"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Эркин формадагы терезелерди түзүү боюнча сынамык функцияны иштетүү"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Эркин формадагы терезелерди түзүү боюнча сынамык функцияны иштетүү."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Компүтердеги бэкаптын сырсөзү"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Компүтердеги толук бэкап учурда корголгон эмес"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Иш тактасынын камдалган сырсөзүн өзгөртүү же алып салуу үчүн таптап коюңуз"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Өчүрүлгөн"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Ар дайым күйгүзүлгөн"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Автоматтык"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView аткарылышы"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView аткарылышын коюу"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"WebView кызматын пайдалануу үчүн аны иштетүү керек. Иштетесизби?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсүн тууралоо"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, иштин майнаптуулугуна таасир этиши мүмкүн."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g>-чакты калды"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - болжол менен <xliff:g id="TIME">%2$s</xliff:g> саат калды"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> толгончо"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Администратор өчүрүп койгон"</string>
     <string name="home" msgid="8263346537524314127">"Башкы бет"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> мурун"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> калды"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index 1419466..7664212 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"ບັງຄັບອະນຸຍາດແອັບ​ຢູ່​ພາຍນອກ"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ເຮັດ​ໃຫ້ທຸກແອັບ​ມີ​ສິດ​ໄດ້ຮັບການຂຽນ​ໃສ່​ບ່ອນ​ຈັດ​ເກັບ​ພາຍນອກ, ໂດຍ​ບໍ່​ຄຳ​ນຶງ​ເຖິງ​ຄ່າ​ທີ່​ຈະ​ແຈ້ງ"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"ບັງ​ຄັງ​ໃຫ້​ກິດ​ຈະ​ກຳ​ປ່ຽນ​ຂະ​ໜາດ​ໄດ້"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"ເຮັດ​ໃຫ້​ທຸກ​ກິດ​ຈະ​ກຳ​ປ່ຽນ​ຂະ​ໜາດ​ໄດ້​ສຳ​ລັບ​ຫຼາຍ​ໜ້າ​ຕ່າງ, ໂດຍ​ບໍ່​ຄຳ​ນຶງ​ເຖິງ​ຄ່າ​ທີ່​ຈະ​ແຈ້ງ."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ເຮັດ​ໃຫ້​ທຸກ​ກິດ​ຈະ​ກຳສາມາດປັບ​ຂະ​ໜາດ​ໄດ້​ສຳ​ລັບ​ຫຼາຍ​ໜ້າ​ຈໍ, ໂດຍ​ບໍ່​ຄຳ​ນຶງ​ເຖິງ​ຄ່າ​ທີ່​ຈະ​ແຈ້ງ."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"ເປີດໃຊ້ໜ້າຕ່າງຮູບແບບອິດສະຫຼະ"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"ເປີດໃຊ້ການຮອງຮັບໜ້າຕ່າງຮູບແບບອິດສະຫຼະທີ່ທົດລອງໃຊ້."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ເປີດໃຊ້ການຮອງຮັບໜ້າຈໍຮູບແບບອິດສະຫຼະແບບທົດລອງ."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ລະຫັດຜ່ານການສຳຮອງຂໍ້ມູນເດັກສະທັອບ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ການ​ສຳຮອງ​ຂໍ້ມູນ​ເຕັມຮູບແບບ​ໃນ​ເດັກສະທັອບ​ຍັງ​ບໍ່​ໄດ້​ຮັບ​ການ​ປ້ອງກັນ​ໃນ​ເວລາ​ນີ້"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ແຕະເພື່ອປ່ຽນ ຫຼືລຶບລະຫັດຂອງການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບໃນເດັກສະທັອບ"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"ປິດໃຊ້ງານແລ້ວ"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"ເປີດຕະຫຼອດ"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ອັດຕະໂນມັດ"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"ການຈັດຕັ້ງປະຕິບັດ WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"ຕັ້ງການຈັດຕັ້ງປະຕິບັດ WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"ການຈັດຕັ້ງປະຕິບັດ WebView ທີ່ເລືອກຖືກປິດນຳໃຊ້, ແລະຕ້ອງຖືກເປີດນຳໃຊ້, ທ່ານຕ້ອງການເປີດນຳໃຊ້ມັນບໍ?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ການ​ປັບ​ແຕ່ງ​ສີ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"​ຄຸນ​ສົມ​ບັດ​ນີ້​ກຳ​ລັງ​ຢູ່​ໃນ​ການ​ທົດ​ລອງ​ແລະ​ອາດ​ມີ​ຜົນ​ຕໍ່​ປະ​ສິດ​ທິ​ພາບ."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ຍັງເຫຼືອປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ​ເຫຼືອປະ​ມານ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງ​ຈະ​ເຕັມ"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"ຖືກປິດໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string>
     <string name="home" msgid="8263346537524314127">"​ໜ້າຫຼັກ"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ກ່ອນນີ້"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"ຍັງເຫຼືອ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 3f5493d..c730dc0 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Priverstinai leisti programas išorinėje atmintin."</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Vis. pr. gal. įr. į vid. saug. nepais. apr. vert."</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Priv. nust., kad veiksm. b. g. atl. kelių d. lang."</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Nustatoma, kad visus veiksmus būtų galima atlikti kelių dydžių languose, nepaisant aprašo verčių."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Nustatyti, kad visus veiksmus būtų galima atlikti kelių dydžių languose, nepaisant aprašo verčių."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Įgalinti laisvos formos langus"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Įgalinamas eksperimentinių laisvos formos langų palaikymas."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Įgalinti eksperimentinių laisvos formos langų palaikymą."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Viet. atsrg. kop. slapt."</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Šiuo metu visos vietinės atsarginės kopijos neapsaugotos"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Jei norite pakeisti ar pašalinti visų stalinio kompiuterio atsarginių kopijų slaptažodį, palieskite"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Išjungta"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Visada įjungta"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatinė"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"„WebView“ diegimas"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"„WebView“ diegimo nustatymas"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Pasirinktas „WebView“ diegimas išjungtas ir jį būtina įgalinti, kad būtų galima naudoti. Ar norite jį įgalinti?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Spalvų taisymas"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ši funkcija yra eksperimentinė ir ji gali turėti įtakos našumui."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Išjungė administratorius"</string>
     <string name="home" msgid="8263346537524314127">"Pagrindinis ekranas"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Prieš <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Liko <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index dd70703..65e4cff 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Lietotņu piespiedu atļaušana ārējā krātuvē"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Ļauj jebkuru lietotni ierakstīt ārējā krātuvē neatkarīgi no manifesta vērtības."</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Pielāgot darbības"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Pielāgo visas darbības vairāku logu režīmam neatkarīgi no vērtībām manifestā."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Pielāgot visas darbības vairāku logu režīmam neatkarīgi no vērtībām manifestā."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Iespējot brīvās formas logus"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Iespējo eksperimentālo brīvās formas logu atbalstu."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Iespējot eksperimentālo brīvās formas logu atbalstu."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Datora dublējuma parole"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Darbvirsmas pilnie dublējumi pašlaik nav aizsargāti."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Pieskarieties, lai mainītu vai noņemtu paroli pilniem datora dublējumiem."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Atspējots"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Vienmēr ieslēgts"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automātiski"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ieviešana"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Iestatīt WebView ieviešanu"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Izvēlētā WebView ieviešana ir atspējota, un tā ir jāiespējo, lai to varētu izmantot. Vai vēlaties to iespējot?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Krāsu korekcija"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Šī funkcija ir eksperimentāla un var ietekmēt veiktspēju."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> — aptuvenais atlikušais laiks: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Atspējojis administrators"</string>
     <string name="home" msgid="8263346537524314127">"Sākums"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Pirms šāda laika: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Atlikušais laiks: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 5bdfd01..4576f3a 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Принуд. дозволете апликации на надворешна меморија"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Запишува апл. во надв.меморија, незав. од манифест"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Принуди ги активностите да ја менуваат големината"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Ги прави сите активности да бидат со променлива големина за мултипрозорец, без разлика на вредностите на манифестот."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Направете сите активности да бидат со променлива големина за повеќе прозорци, без разлика на вредностите на манифестот."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Овозможи прозорци со слободна форма"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Овозможува поддршка за експериментални прозорци со слободна форма."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Овозможи поддршка за експериментални прозорци со слободна форма."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Резервна лозинка за работна површина"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Целосни резервни копии на работната површина кои во моментов не се заштитени"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Допрете за да се промени или отстрани лозинката за целосни резервни копии на работната површина"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Оневозможено"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Секогаш вклучено"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Автоматски"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Воведување WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Поставете воведување WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Избраната примена на WebView е оневозможена, а за да се користи, мора да се овозможи. Дали сакате да ја овозможите?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција на боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Преостанаа прибл. <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Преостанаа прибл. <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостанува приближно <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна"</string>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 38b4771..180d615 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"ബാഹ്യമായതിൽ നിർബന്ധിച്ച് അനുവദിക്കുക"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, ബാഹ്യ സ്റ്റോറേജിലേക്ക് എഴുതപ്പെടുന്നതിന് ഏതൊരു ആപ്പിനെയും യോഗ്യമാക്കുന്നു"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"വലിപ്പം മാറ്റാൻ പ്രവർത്തനങ്ങളെ നിർബന്ധിക്കുക"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, എല്ലാ പ്രവർത്തനങ്ങളെയും മൾട്ടി-വിൻഡോയ്ക്കായി വലിപ്പം മാറ്റുന്നു."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, എല്ലാ ആക്ടിവിറ്റികളെയും മൾട്ടി-വിൻഡോയ്ക്കായി വലിപ്പം മാറ്റുക."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"ഫ്രീഫോം വിൻഡോകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"പരീക്ഷണാത്മക ഫ്രീഫോം വിൻഡോകൾക്കുള്ള പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുന്നു."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"പരീക്ഷണാത്മക ഫ്രീഫോം വിൻഡോകൾക്കുള്ള പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുക."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ഡെ‌സ്‌ക്ടോപ്പ് ബാക്കപ്പ് പാസ്‌വേഡ്"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ഡെസ്‌ക്‌ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾ നിലവിൽ പരിരക്ഷിച്ചിട്ടില്ല"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ഡെസ്‌ക്‌ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾക്കായി പാസ്‌വേഡുകൾ മാറ്റാനോ നീക്കംചെയ്യാനോ ടാപ്പുചെയ്യുക"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"എല്ലായ്‌പ്പോഴും ഓണാണ്"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ഓട്ടോമാറ്റിക്"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView നടപ്പാക്കൽ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView നടപ്പാക്കൽ സജ്ജമാക്കുക"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"തിരഞ്ഞെടുത്ത WebView നടപ്പാക്കൽ പ്രവർത്തനരഹിതമാക്കി, ഉപയോഗിക്കുന്നതിന് ഇത് പ്രവർത്തനക്ഷമമാക്കണം, പ്രവർത്തനക്ഷമമാക്കാൻ ആഗ്രഹിക്കുന്നുണ്ടോ?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"വർണ്ണം ക്രമീകരിക്കൽ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ഈ ഫീച്ചർ പരീക്ഷണാത്മകമായതിനാൽ പ്രകടനത്തെ ബാധിച്ചേക്കാം."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index 3b5d5f1..8bdd880 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Апп-ыг гадаад санах ойд хадгалахыг зөвшөөрөх"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Манифест утгыг нь үл хамааран дурын апп-ыг гадаад санах ойд бичих боломжтой болгодог"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Үйл ажиллагааны хэмжээг өөрчилж болохуйц болгох"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Тодорхойлогч файлын утгыг үл хамааран, бүх үйл ажиллагааг олон цонхонд хэмжээг нь өөрчилж болохуйц болгох."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Тодорхойлогч файлын утгыг үл хамааран, бүх үйл ажиллагааны хэмжээг олон цонхонд өөрчилж болохуйц болгоно уу."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Чөлөөт хэлбэрийн цонхыг идэвхжүүлэх"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Туршилтын чөлөөт хэлбэрийн цонхны дэмжлэгийг идэвхжүүлдэг."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Туршилтын чөлөөт хэлбэрийн цонхны дэмжлэгийг идэвхжүүлнэ үү."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Десктоп нөөшлөлтийн нууц үг"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Десктоп бүрэн нөөцлөлт одоогоор хамгаалалтгүй байна"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Компьютерийн бүтэн нөөцлөлтийн нууц үгийг өөрчлөх, устгах бол дарна уу"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Идэвхгүй"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Байнга асаалттай"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Автоматаар"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView хэрэгжилт"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView хэрэгжилтийг тохируулах"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Сонгосон WebView хэрэгжүүлэлтийг идэвхгүй болгосон бөгөөд хэрэглэхийн тулд заавал идэвхжүүлэх шаардлагатай. Үүнийг идэвхжүүлэх үү?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Өнгө тохируулах"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Энэ функц туршилтынх бөгөөд ажиллагаанд нөлөөлж болзошгүй."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Админ идэвхгүй болгосон"</string>
     <string name="home" msgid="8263346537524314127">"Нүүр"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> өмнө"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> үлдсэн"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index 493f579..92247f5 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"बाह्यवर अॅप्सना अनुमती देण्याची सक्ती करा"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"मॅनिफेस्ट मूल्यांकडे दुर्लक्ष करून, कोणत्याही अॅपला बाह्य संचयनावर लेखन केले जाण्‍यासाठी पात्र बनविते"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"क्र‍ियाकलापाचा आकार बदलण्यायोग्य होण्याची सक्ती करा"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"मॅनिफेस्ट मूल्यांकडे दुर्लक्ष करून, एकाधिक-विंडोसाठी सर्व क्रियाकलापांचा आकार बदलण्यायोग्य करा"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"मॅनिफेस्ट मूल्यांकडे दुर्लक्ष करून, एकाधिक-विंडोसाठी सर्व क्रियाकलापांचा आकार बदलण्यायोग्य करा."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"freeform विंडो सक्षम करा"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"प्रायोगिक मुक्तस्वरूपाच्या विंडोसाठी समर्थन सक्षम करते."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"प्रायोगिक मुक्तस्वरूपाच्या विंडोसाठी समर्थन सक्षम करा."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"डेस्कटॉप बॅकअप संकेतशब्द"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"डेस्कटॉप पूर्ण बॅक अप सध्या संरक्षित नाहीत"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"डेस्कटॉपच्या पूर्ण बॅकअपसाठी असलेला संकेतशब्द बदलण्यासाठी किंवा काढण्यासाठी टॅप  करा"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"अक्षम केले"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"नेहमी चालू"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"स्वयंचलित"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"वेबदृश्य अंमलबजावणी"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"वेबदृश्य अंमलबजावणी सेट करा"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"निवडलेली WebView अंमलबजावणी अक्षम आहे आणि वापरण्यास सक्षम असणे आवश्यक आहे, आपण ती सक्षम करू इच्छिता?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधारणा"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"हे वैशिष्‍ट्य प्रायोगिक आहे आणि कदाचित कार्यप्रदर्शन प्रभावित करू शकते."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"अंदाजे. <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"अंदाजे. <xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - अंदाजे. <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण होण्यात"</string>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 0509159..45f5c6f 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Benarkan apl secara paksa pada storan luaran"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Menjadikan sebarang apl layak ditulis ke storan luaran, walau apa juga nilai manifesnya"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Paksa aktiviti supaya boleh diubah saiz"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Menjadikan semua aktiviti boleh diubah saiz untuk berbilang tetingkap, tanpa mengambil kira nilai manifes."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Bolehkan semua saiz aktiviti diubah untuk berbilang tetingkap, tanpa mengambil kira nilai manifes."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Dayakan tetingkap bentuk bebas"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Mendayakan sokongan untuk tetingkap bentuk bebas percubaan."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Dayakan sokongan untuk tetingkap bentuk bebas percubaan."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Kata laluan sandaran komputer meja"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Sandaran penuh komputer meja tidak dilindungi pada masa ini"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ketik untuk menukar atau mengalih keluar kata laluan untuk sandaran penuh desktop"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Dilumpuhkan"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Sentiasa hidup"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatik"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Pelaksanaan WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Tetapkan pelaksanaan WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Pelaksanaan WebView pilihan telah dilumpuhkan dan mesti didayakan untuk digunakan, adakah anda mahu mendayakannya?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pembetulan warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ciri ini adalah percubaan dan boleh menjejaskan prestasi."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira. <xliff:g id="TIME">%2$s</xliff:g> yang tinggal"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Dilumpuhkan oleh pentadbir"</string>
     <string name="home" msgid="8263346537524314127">"Skrin Utama"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> yang lalu"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> lagi"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index 9f56479..9d722db 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"အပြင်မှာ အတင်း ခွင့်ပြုရန်"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ပြနေတဲ့ တန်ဖိုး ဘယ်လိုပဲရှိနေနေ၊ ဘယ် appကို မဆို အပြင် သိုလှောင်ခန်းသို့ ရေးသားခွင့် ပေးတယ်"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"လုပ်ဆောင်ချက်များ ဆိုက်ညှိရနိုင်ရန် လုပ်ခိုင်းပါ"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"မန်နီးဖက်စ် တန်ဖိုးမရွေး၊ လုပ်ဆောင်ချက် အားလုံး ဆိုက်ညှိရနိုင်အောင် လုပ်ပေးပါ။"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"မန်နီးဖက်စ်တန်ဖိုးများ မည်မျှပင်ရှိစေကာမူ၊ ဝင်းဒိုးများအတွက် လှုပ်ရှားမှုများအားလုံးကို အရွယ်အစားချိန်ခြင်း ပြုလုပ်ပါ။"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"အခမဲ့ပုံစံ ဝင်းဒိုးကို ဖွင့်ပါ"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"စမ်းသပ်မှု အခမဲ့ပုံစံ ဝင်းဒိုးများအတွက် ပံ့ပိုးမှုကို ဖွင့်ပါ။"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ပုံစံမျိုးစုံဝင်းဒိုးများစမ်းသပ်မှုအတွက် အထောက်အပံ့ကိုဖွင့်ပါ"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop အရန်စကားဝှက်"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"အလုပ်ခုံတွင် အရန်သိမ်းဆည်းခြင်းများကို လောလောဆယ် မကာကွယ်နိုင်ပါ။"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"စားပွဲတင်ကွန်ပျူတာကို အပြည့်အဝအရံကူးထားရန်အတွက် စကားဝှက်ကို ပြောင်းရန် သို့မဟုတ် ဖယ်ရှားရန် တို့ပါ။"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"ပိတ်ထား"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"အမြဲတမ်း ဖွင့်ထားရန်"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"အလိုအလျောက်"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView အကောင်အထည်ဖော်မှု"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView အကောင်အထည်ဖော်မှု သတ်မှတ်ပါ"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"ရွေးချယ်ထားသည့် WebView လုပ်ဆောင်ခြင်းကို ပိတ်ထားသည်ပြီး အသုံးပြုရန်အတွက် ဖွင့်ရမည်၊ ဖွင့်လိုပါသလား။"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"အရောင်ပြင်ဆင်မှု"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ဒီအင်္ဂါရပ်မှာ စမ်းသပ်မှု ဖြစ်၍ လုပ်ကိုင်မှုကို အကျိုးသက်ရောက်နိုင်သည်။"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ခန့်မှန်းခြေ <xliff:g id="TIME">%1$s</xliff:g> ကျန်ပါသည်"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ခန့်မှန်းခြေ။ <xliff:g id="TIME">%2$s</xliff:g> ကျန်ရှိနေ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> အပြည့်အထိ"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"စီမံခန့်ခွဲသူမှ ပိတ်ထားသည်"</string>
     <string name="home" msgid="8263346537524314127">"ပင်မ"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"ပြီးခဲ့သည့် <xliff:g id="ID_1">%1$s</xliff:g> က"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ကျန်ပါသည်"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 013fe26..ff15482 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Tving frem tillatelse for ekstern lagring av apper"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Gjør at apper kan skrives til ekstern lagring, uavhengig av manifestverdier"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Tving aktiviteter til å kunne endre størrelse"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Dette gjør at alle aktivitene kan endre størrelse for flervindusmodus, uavhengig av manifestverdier."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Gjør at alle aktivitetene kan endre størrelse for flervindusmodus, uavhengig av manifestverdier."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Slå på vinduer i fritt format"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Slår på støtte for vinduer i eksperimentelt fritt format."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Slå på støtte for vinduer i eksperimentelt fritt format."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Passord for sikkerhetskopiering på datamaskin"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Fullstendig sikkerhetskopiering på datamaskin beskyttes ikke for øyeblikket."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Trykk for å endre eller fjerne passordet for fullstendige sikkerhetskopier på datamaskinen"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Slått av"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Alltid på"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisk"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Angi WebView-implementering"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Den valgte implementeringen av nettvisningen er slått av – den må slås på for å brukes. Vil du slå den på?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Fargekorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funksjonen er eksperimentell og kan påvirke ytelsen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> igjen"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Avslått av administratoren"</string>
     <string name="home" msgid="8263346537524314127">"Startside"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> siden"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> gjenstår"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index 715f055..f0cfdab 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"बाह्यमा बल प्रयोगको अनुमति प्राप्त अनुप्रयोगहरू"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"म्यानिफेेस्टको उपेक्षा गरी, कुनै पनि अनुप्रयोगलाई बाह्य भण्डारणमा लेख्न योग्य बनाउँछ"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"गतिविधिहरू रिसाइज गर्नको लागि बाध्य गर्नुहोस्"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"म्यानिफेेस्ट मानहरूको ख्याल नगरी, बहु-विन्डोको लागि सबै रिसाइज गर्न सकिने गतिविधिहरू बनाउँछ।"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"म्यानिफेेस्ट मानहरूको ख्याल नगरी, बहु-विन्डोको लागि सबै रिसाइज गर्न सकिने गतिविधिहरू बनाउँछ।"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"फ्रिफर्म विन्डोहरू सक्रिय गर्नुहोस्"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"प्रयोगात्मक फ्रिफर्म विन्डोहरूका लागि समर्थनलाई सक्रिय गर्छ।"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"प्रयोगात्मक फ्रिफर्म विन्डोहरूका लागि समर्थन सक्रिय गर्नुहोस्।"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"डेस्कटप ब्याकअप पासवर्ड"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"डेस्कटप पूर्ण जगेडाहरू हाललाई सुरक्षित छैनन्"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"डेस्कटप पूर्ण ब्याकअपको लागि पासवर्ड बदल्न वा हटाउन ट्याप गर्नुहोस्"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"असक्षम गरियो"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"सधैं खुल्‍ला"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"स्वचालित"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView कार्यान्वयन"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView कार्यान्वयन सेट गर्नुहोस्"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"छनौट गरिएको WebView को कार्यान्वयन असक्षम गरिएको छ र प्रयोग गर्नका लागि सक्रिय गर्नुपर्छ, तपाईँ यसलाई सक्रिय गर्न चाहनुहुन्छ?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रङ्ग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यो सुविधा प्रयोगात्मक छ र प्रदर्शनमा असर गर्न सक्छ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%2$s</xliff:g> बाँकी छ"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी छ"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग। <xliff:g id="TIME">%2$s</xliff:g> बायाँ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण नभए सम्म"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index bd24201..0dbf5b9 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Toestaan van apps op externe opslag afdwingen"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Hierdoor komt een app in aanmerking om te worden geschreven naar externe opslag, ongeacht de manifestwaarden"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Formaat activiteiten geforceerd aanpasbaar maken"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Hiermee wordt het formaat van alle activiteiten aanpasbaar gemaakt, ongeacht de manifestwaarden."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Het formaat van alle activiteiten aanpasbaar maken, ongeacht de manifestwaarden."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Vensters met vrije vorm inschakelen"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Schakelt ondersteuning in voor vensters met experimentele vrije vorm."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Ondersteuning voor vensters met experimentele vrije vorm inschakelen."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Wachtwoord desktopback-up"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Volledige back-ups naar desktops zijn momenteel niet beveiligd"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tik om het wachtwoord voor volledige back-ups naar desktops te wijzigen of te verwijderen"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Uitgeschakeld"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Altijd aan"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisch"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementatie"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-implementatie instellen"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"De gekozen WebView-implementatie is uitgeschakeld en moet worden ingeschakeld voor gebruik. Wil je deze inschakelen?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurcorrectie"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Deze functie is experimenteel en kan invloed hebben op de prestaties."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> resterend"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ca. <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Uitgeschakeld door beheerder"</string>
     <string name="home" msgid="8263346537524314127">"Startpagina"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> geleden"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> resterend"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index f9c0c11..2f44757 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"ਐਪਸ ਨੂੰ ਬਾਹਰਲੇ ਤੇ ਜ਼ਬਰਦਸਤੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ਇੱਕ ਐਪ ਨੂੰ ਬਾਹਰਲੀ ਸਟੋਰੇਜ ਤੇ ਲਿਖਣ ਦੇ ਯੋਗ ਬਣਾਉਂਦਾ ਹੈ, ਮੈਨੀਫੈਸਟ ਵੈਲਯੂਜ ਤੇ ਵਿਚਾਰ ਕੀਤੇ ਬਿਨਾਂ"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"ਮੁੜ-ਆਕਾਰ ਬਦਲਣ ਲਈ ਸਰਗਰਮੀਆਂ \'ਤੇ ਜ਼ੋਰ ਦਿਓ"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"ਮਲਟੀ-ਵਿੰਡੋ ਲਈ ਸਾਰੀਆਂ ਸਰਗਰਮੀਆਂ ਨੂੰ ਮੁੜ-ਆਕਾਰ ਵਿੱਚ ਲਿਆਉਂਦੀ ਹੈ, ਚਾਹੇ ਮੈਨੀਫੈਸਟ ਵੈਲਯੂਜ਼ ਕੁਝ ਵੀ ਹੋਣ।"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ਮੈਨੀਫੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਮਲਟੀ-ਵਿੰਡੋ ਲਈ ਸਾਰੀਆਂ ਸਰਗਰਮੀਆਂ ਨੂੰ ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਓ।"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"freeform windows ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"ਪ੍ਰਯੋਗਾਤਮਕ freeform windows ਲਈ ਸਮਰਥਨ ਨੂੰ ਯੋਗ ਬਣਾਉਂਦੀ ਹੈ।"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ਪ੍ਰਯੋਗਮਈ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਲਈ ਸਮਰਥਨ ਨੂੰ ਯੋਗ ਬਣਾਓ।"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ਡੈਸਕਟੌਪ ਬੈਕਅਪ ਪਾਸਵਰਡ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ਡੈਸਕਟੌਪ ਪੂਰੇ ਬੈਕਅਪਸ ਇਸ ਵੇਲੇ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਹਨ"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ਡੈਸਕਟਾਪ ਦੇ ਮੁਕੰਮਲ ਬੈਕਅੱਪਾਂ ਲਈ ਪਾਸਵਰਡ ਨੂੰ ਬਦਲਣ ਜਾਂ ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"ਅਸਮਰੱਥ ਬਣਾਇਆ"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"ਹਮੇਸ਼ਾ ਚਾਲੂ"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ਆਟੋਮੈਟਿਕ"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ਅਮਲ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView ਅਮਲ ਸੈੱਟ ਕਰੋ"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"ਚੁਣਿਆ ਗਿਆ WebView ਅਮਲ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ, ਅਤੇ ਵਰਤੋਂ ਕਰਨ ਲਈ ਇਸ ਨੂੰ ਯੋਗ ਬਣਾਇਆ ਜਾਣਾ ਜ਼ਰੂਰੀ ਹੈ, ਕੀ ਤੁਸੀਂ ਇਸ ਨੂੰ ਯੋਗ ਬਣਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ਰੰਗ ਸੰਸ਼ੋਧਨ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਾਤਮਿਕ ਹੈ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਤੇ ਅਸਰ ਪਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 4ff0d03..e30925c 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Wymuś zezwalanie na aplikacje w pamięci zewn."</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Pozwala na zapis aplikacji w pamięci zewn. niezależnie od wartości w pliku manifestu"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Wymuś zmianę rozmiaru okien aktywności"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Umożliwia zmianę rozmiaru wszystkich okien aktywności w trybie wielu okien niezależnie od ustawień w pliku manifestu."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Zezwól na zmianę rozmiaru wszystkich okien aktywności w trybie wielu okien niezależnie od ustawień w pliku manifestu."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Włącz dowolny rozmiar okien"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Włącza obsługę eksperymentalnej funkcji dowolnego rozmiaru okien."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Włącz obsługę eksperymentalnej funkcji dowolnego rozmiaru okien."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Hasło kopii zapasowej"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Pełne kopie zapasowe na komputerze nie są obecnie chronione"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dotknij, by zmienić lub usunąć hasło pełnych kopii zapasowych na komputerze."</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Wyłączone"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Zawsze włączone"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatycznie"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementacja WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Ustaw implementację WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Wybrana implementacja WebView jest wyłączona. Aby jej używać, musisz ją włączyć. Chcesz to zrobić?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcja kolorów"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To jest funkcja eksperymentalna i może wpływać na działanie urządzenia."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Pozostało około <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało ok. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Wyłączone przez administratora"</string>
     <string name="home" msgid="8263346537524314127">"Ekran główny"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> temu"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Pozostało: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index b4251a5..ec54e4f 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forçar permissão de apps em armazenamento externo"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Qualifica apps p/ gravação em armazenamento externo, independentemente de valores de manifestos"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forçar atividades a serem redimensionáveis"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Torna todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Ativar janelas de forma livre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ativa a compatibilidade com janelas de forma livre experimentais."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Ativar a compatibilidade com janelas de forma livre experimentais."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Senha do backup local"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Os backups completos do computador não estão protegidos no momento"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toque para alterar ou remover a senha de backups completos do desktop"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Desativada"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Sempre ativada"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementação do WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configurar implementação do WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementação do WebView escolhida está desativada e deve ser ativada para ser usada. Deseja ativá-la?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Desativada pelo administrador"</string>
     <string name="home" msgid="8263346537524314127">"Início"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> atrás"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> restante(s)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 3dd9561..ab2a5ae 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forçar perm. de aplicações no armazenamento ext."</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Qualquer aplic. pode ser gravada no arm. ext., independ. dos valores do manif."</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forçar as atividades a serem redimensionáveis"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Torna todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Ativar janelas de forma livre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ativa a compatibilidade com janelas de forma livre experimentais."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Ativar a compatibilidade com janelas de forma livre experimentais."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Palavra-passe cópia do comp."</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"As cópias de segurança completas no ambiente de trabalho não estão atualmente protegidas"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tocar para alterar ou remover a palavra-passe para cópias de segurança completas no ambiente de trabalho"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Desativado"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Sempre ativado"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementação WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Definir implementação WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementação WebView escolhida foi desativada e tem de ser ativada para poder ser utilizada. Pretende ativá-la?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta funcionalidade é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Resta(m) aproximadamente <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Resta(m) aproximadamente <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) aprox. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index b4251a5..ec54e4f 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forçar permissão de apps em armazenamento externo"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Qualifica apps p/ gravação em armazenamento externo, independentemente de valores de manifestos"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forçar atividades a serem redimensionáveis"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Torna todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Ativar janelas de forma livre"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ativa a compatibilidade com janelas de forma livre experimentais."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Ativar a compatibilidade com janelas de forma livre experimentais."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Senha do backup local"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Os backups completos do computador não estão protegidos no momento"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toque para alterar ou remover a senha de backups completos do desktop"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Desativada"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Sempre ativada"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementação do WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configurar implementação do WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementação do WebView escolhida está desativada e deve ser ativada para ser usada. Deseja ativá-la?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Desativada pelo administrador"</string>
     <string name="home" msgid="8263346537524314127">"Início"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> atrás"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> restante(s)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index e883d0a..0cfacd7 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -85,7 +85,7 @@
     <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Semnal Wi-Fi: complet."</string>
     <string name="process_kernel_label" msgid="3916858646836739323">"Sistem de operare Android"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicații eliminate"</string>
-    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplicaţii și utilizatori eliminaţi"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplicații și utilizatori eliminați"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"Tethering prin USB"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Hotspot portabil"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Tethering prin Bluetooth"</string>
@@ -102,7 +102,7 @@
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Ritmul vorbirii"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Viteza cu care este vorbit textul"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"Limbă"</string>
-    <string name="tts_lang_use_system" msgid="2679252467416513208">"Utilizaţi limba sistemului"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"Utilizați limba sistemului"</string>
     <string name="tts_lang_not_selected" msgid="7395787019276734765">"Nu ați selectat limba"</string>
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"Setează vocea caracteristică limbii pentru textul vorbit"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"Ascultați un exemplu"</string>
@@ -110,7 +110,7 @@
     <string name="tts_install_data_title" msgid="4264378440508149986">"Instalați date vocale"</string>
     <string name="tts_install_data_summary" msgid="5742135732511822589">"Instalați datele vocale necesare pentru sintetizarea vorbirii"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Acest motor de sintetizare a vorbirii poate culege în întregime textul vorbit, inclusiv datele personale cum ar fi parolele și numerele cărților de credit. Metoda provine de la motorul <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Permiteți utilizarea acestui motor de sintetizare a vorbirii?"</string>
-    <string name="tts_engine_network_required" msgid="1190837151485314743">"Pentru rezultatul transformării textului în vorbire pentru această limbă este necesară o conexiune de rețea care să funcţioneze."</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"Pentru rezultatul transformării textului în vorbire pentru această limbă este necesară o conexiune de rețea care să funcționeze."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Acesta este un exemplu de sintetizare a vorbirii"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"Starea limbii prestabilite"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> este acceptată integral"</string>
@@ -175,7 +175,7 @@
     <string name="select_usb_configuration_title" msgid="2649938511506971843">"Selectați configurația USB"</string>
     <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Selectați configurația USB"</string>
     <string name="allow_mock_location" msgid="2787962564578664888">"Permiteți locațiile fictive"</string>
-    <string name="allow_mock_location_summary" msgid="317615105156345626">"Permiteți locaţiile fictive"</string>
+    <string name="allow_mock_location_summary" msgid="317615105156345626">"Permiteți locațiile fictive"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activați inspectarea atributelor de vizualizare"</string>
     <string name="legacy_dhcp_client_summary" msgid="163383566317652040">"Folosiți clientul DHCP din Lollipop în locul noului client Android DHCP."</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Păstrați întotdeauna conexiunea de date mobile activată, chiar și atunci când funcția Wi‑Fi este activată (pentru comutarea rapidă între rețele)."</string>
@@ -183,7 +183,7 @@
     <string name="adb_warning_message" msgid="7316799925425402244">"Depanarea USB are exclusiv scopuri de dezvoltare. Utilizați-o pentru a copia date de pe computer pe dispozitiv, pentru a instala aplicații pe dispozitiv fără notificare și pentru a citi datele din jurnale."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revocați accesul la remedierea erorilor prin USB de pe toate computerele pe care le-ați autorizat anterior?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Permiteți setările pentru dezvoltare?"</string>
-    <string name="dev_settings_warning_message" msgid="2298337781139097964">"Aceste setări sunt destinate exclusiv utilizării pentru dezvoltare. Din cauza lor, este posibil ca dispozitivul dvs. și aplicațiile de pe acesta să nu mai funcţioneze sau să funcţioneze necorespunzător."</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"Aceste setări sunt destinate exclusiv utilizării pentru dezvoltare. Din cauza lor, este posibil ca dispozitivul dvs. și aplicațiile de pe acesta să nu mai funcționeze sau să funcționeze necorespunzător."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificați aplicațiile prin USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Verificați aplicațiile instalate utilizând ADB/ADT, pentru a detecta un comportament dăunător."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Dezactivează funcția Bluetooth de volum absolut în cazul problemelor de volum apărute la dispozitivele la distanță, cum ar fi volumul mult prea ridicat sau lipsa de control asupra acestuia."</string>
@@ -194,11 +194,11 @@
     <string name="debug_debugging_category" msgid="6781250159513471316">"Depanare"</string>
     <string name="debug_app" msgid="8349591734751384446">"Selectați aplicația de depanare"</string>
     <string name="debug_app_not_set" msgid="718752499586403499">"Nu ați setat o aplicație de depanare"</string>
-    <string name="debug_app_set" msgid="2063077997870280017">"Aplicaţie de depanare: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="select_application" msgid="5156029161289091703">"Selectaţi o aplicație"</string>
+    <string name="debug_app_set" msgid="2063077997870280017">"Aplicație de depanare: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="5156029161289091703">"Selectați o aplicație"</string>
     <string name="no_application" msgid="2813387563129153880">"Niciuna"</string>
-    <string name="wait_for_debugger" msgid="1202370874528893091">"Aşteptaţi depanatorul"</string>
-    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"Înaintea executării, aplicația aşteaptă atașarea depanatorului"</string>
+    <string name="wait_for_debugger" msgid="1202370874528893091">"Așteptați depanatorul"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"Înaintea executării, aplicația așteaptă atașarea depanatorului"</string>
     <string name="debug_input_category" msgid="1811069939601180246">"Intrare"</string>
     <string name="debug_drawing_category" msgid="6755716469267367852">"Desen"</string>
     <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Redare accelerată hardware"</string>
@@ -218,7 +218,7 @@
     <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"Straturile hardware clipesc verde la actualizare"</string>
     <string name="debug_hw_overdraw" msgid="2968692419951565417">"Depanați suprapunerea"</string>
     <string name="disable_overlays" msgid="2074488440505934665">"Dezactivați suprapun. HW"</string>
-    <string name="disable_overlays_summary" msgid="3578941133710758592">"Utilizaţi mereu GPU pentru compunerea ecranului"</string>
+    <string name="disable_overlays_summary" msgid="3578941133710758592">"Utilizați mereu GPU pentru compunerea ecranului"</string>
     <string name="simulate_color_space" msgid="6745847141353345872">"Simulați spațiu culoare"</string>
     <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Monitorizări OpenGL"</string>
     <string name="usb_audio_disable_routing" msgid="8114498436003102671">"Dezactivați rutarea audio USB"</string>
@@ -239,7 +239,7 @@
     <string name="transition_animation_scale_title" msgid="387527540523595875">"Scară tranziție animații"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"Scară durată Animator"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"Simulați afișaje secundare"</string>
-    <string name="debug_applications_category" msgid="4206913653849771549">"Aplicaţii"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"Aplicații"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"Nu păstrați activitățile"</string>
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"Elimină activitățile imediat ce utilizatorul le închide"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"Limită procese fundal"</string>
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forțați accesul aplicațiilor la stocarea externă"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Face orice aplicație eligibilă să fie scrisă în stocarea externă, indiferent de valorile manifestului"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forțați redimensionarea activităților"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Permite redimensionarea tuturor activităților pentru modul cu ferestre multiple, indiferent de valorile manifestului."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Permiteți redimensionarea tuturor activităților pentru modul cu ferestre multiple, indiferent de valorile manifestului."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Activați ferestrele cu formă liberă"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Activează compatibilitatea pentru ferestrele experimentale cu formă liberă."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Activați compatibilitatea pentru ferestrele experimentale cu formă liberă."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Parolă copie rez. desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"În prezent, copiile de rezervă complete pe desktop nu sunt protejate"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Atingeți ca să modificați sau să eliminați parola pentru backupurile complete pe desktop"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Dezactivată"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Activată permanent"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automat"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementare WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Setați implementarea WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Implementarea WebView aleasă este dezactivată. Pentru a fi folosită, trebuie să fie activată. Doriți să o activați?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corecția culorii"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Această funcție este experimentală și poate afecta performanțele."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Timp rămas: aproximativ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Dezactivată de administrator"</string>
     <string name="home" msgid="8263346537524314127">"Ecranul principal"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Acum <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Timp rămas: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 0f4eaa1..4b3214a 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Разрешить сохранение на внешние накопители"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Разрешает сохранение приложений на внешние накопители независимо от значения манифеста"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Изменение размера в многооконном режиме"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Позволяет менять размер в многооконном режиме (независимо от значений манифеста)"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Разрешить изменение размера в многооконном режиме (независимо от значений манифеста)"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Разрешить создание окон произвольной формы"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Включить экспериментальную функцию создания окон произвольной формы"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Включить экспериментальную функцию создания окон произвольной формы"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Пароль для резервного копирования"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Полные резервные копии в настоящее время не защищены"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Нажмите, чтобы изменить или удалить пароль для резервного копирования"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Отключено"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Всегда включено"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Автоматическое переключение"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Сервис WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Настройки сервиса WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Чтобы использовать сервис WebView, включите его. Сделать это?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Коррекция цвета"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Это экспериментальная функция, она может снизить производительность устройства."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось около <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Отключено администратором"</string>
     <string name="home" msgid="8263346537524314127">"Главная"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> назад"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Осталось <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index 6483b18..390e218 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"බාහිර මත යෙදුම් ඉඩ දීම බල කරන්න"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"මැනිෆෙස්ට් අගයන් නොසලකා, ඕනෑම යෙදුමක් අභ්‍යන්තර ගබඩාවට ලිවීමට සුදුසුකම් ලබා දෙයි"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"ක්‍රියාකාරකම් ප්‍රතිප්‍රමාණ කළ හැකි බවට බල කරන්න"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"මැනිෆෙස්ට් අගයන් නොසලකා, සියලු ක්‍රියාකාරකම් බහු-කවුළු සඳහා ප්‍රතිප්‍රමාණ කළ හැකි බවට පත් කරයි."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"මැනිෆෙස්ට් අගයන් නොසලකා, සියලු ක්‍රියාකාරකම් බහු-කවුළුව සඳහා ප්‍රතිප්‍රමාණ කළ හැකි බවට පත් කරන්න."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"අනියම් හැඩැති කවුළු සබල කරන්න"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"පරීක්ෂණාත්මක අනියම් හැඩැති කවුළු සඳහා සහාය සබල කරයි."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"පරීක්ෂණාත්මක අනියම් හැඩැති කවුළු සඳහා සහාය සබල කරන්න."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ඩෙස්ක්ටොප් උපස්ථ මුරපදය"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ දැනට ආරක්ෂා කර නොමැත"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ සඳහා මුරපදය වෙනස් කිරීමට හෝ ඉවත් කිරීමට තට්ටු කරන්න"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"අබලයි"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"සැමවිට ක්‍රියාත්මක"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"ස්වයංක්‍රීය"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ක්‍රියාත්මක කිරීම"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView ක්‍රියාත්මක කිරීම සකසන්න"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"තෝරන ලද WebView ක්‍රියාත්මක කිරීම අබල අතර, භාවිත කිරීමට සබල කළ යුතුය, ඔබ එය සබල කිරීමට අදහස් කරන්නේද?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"වර්ණ නිවැරදි කිරීම"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"මෙම විශේෂාංගය පරීක්ෂණාත්මක සහ ඇතැම් විට ක්‍රියාකාරිත්වයට බලපෑ හැක."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"දළ වශයෙන් <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරිය"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආසන්න <xliff:g id="TIME">%2$s</xliff:g> වම"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"පරිපාලක විසින් අබල කරන ලදී"</string>
     <string name="home" msgid="8263346537524314127">"මුල් පිටුව"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>කට පෙර"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g>ක් ඉතිරිය"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index d8e2389..8bf64fa 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Vynútiť povolenie aplikácií na externom úložisku"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Umožňuje zapísať akúkoľvek aplikáciu do externého úložiska bez ohľadu na hodnoty v manifeste"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Vynútiť možnosť zmeny veľkosti aktivít"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Veľkosti všetkých aktivít bude možné zmeniť na niekoľko okien (bez ohľadu na hodnoty manifestu)."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Veľkosti všetkých aktivít bude možné zmeniť na niekoľko okien (bez ohľadu na hodnoty manifestu)."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Povoliť okná s voľným tvarom"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Povolenie podpory pre experimentálne okná s voľným tvarom."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Povolenie podpory pre experimentálne okná s voľným tvarom."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Heslo pre zálohy v počítači"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Úplné zálohy na počítači nie sú momentálne chránené"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Klepnutím zmeníte alebo odstránite heslo pre úplné zálohy do počítača"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Vypnuté"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Vždy zapnuté"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatický"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementácia komponenta WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Nastavenie implementácie komponenta WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Zvolená implementácia technológie WebView je zakázaná. Ak ju chcete použiť, musíte ju najprv povoliť. Chcete ju povoliť?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Úprava farieb"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkcia je experimentálna a môže mať vplyv na výkonnosť."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zostáva cca. <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostáva približne <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Zakázané správcom"</string>
     <string name="home" msgid="8263346537524314127">"Domov"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"pred <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Zostáva <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index fa0e784..42e589b 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Vsili omogočanje aplikacij v zunanji shrambi"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsako aplikacijo zapisati v zunanjo shrambo"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Vsili povečanje velikosti za aktivnosti"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsem aktivnostim povečati velikost za način z več okni."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsem aktivnostim povečati velikost za način z več okni."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Omogočanje oken svobodne oblike"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Omogočanje podpore za poskusna okna svobodne oblike"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Omogočanje podpore za poskusna okna svobodne oblike"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Geslo za varn. kop. rač."</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Popolne varnostne kopije namizja trenutno niso zaščitene"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dotaknite se, če želite spremeniti ali odstraniti geslo za popolno varnostno kopiranje namizja"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Onemogočeno"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Vedno vklopljeno"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Samodejno"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Izvedba spletnega pogleda"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Nastavitev izvedbe spletnega pogleda"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Izbrana izvedba spletnega pogleda je onemogočena in jo morate omogočiti, če jo želite uporabljati. Ali jo želite omogočiti?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Popravljanje barv"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To je preskusna funkcija in lahko vpliva na učinkovitost delovanja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Še približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index f9b62fb..4c77a12 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Detyro lejimin në hapësirën e jashtme"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Bën që çdo aplikacion të jetë i përshtatshëm për t\'u shkruar në hapësirën ruajtëse të jashtme, pavarësisht nga vlerat e manifestit"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Detyro madhësinë e ndryshueshme për aktivitetet"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Bën që të gjitha aktivitetet të kenë madhësi të ndryshueshme për përdorimin me shumë dritare, pavarësisht vlerave të manifestit."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Bëj që të gjitha aktivitetet të kenë madhësi të ndryshueshme për përdorimin me shumë dritare, pavarësisht vlerave të manifestit."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Aktivizo dritaret me formë të lirë"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktivizon mbështetjen për dritaret eksperimentale me formë të lirë."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktivizo mbështetjen për dritaret eksperimentale me formë të lirë."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Fjalëkalimi rezervë i kompjuterit"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Rezervimet e plota në kompjuter nuk janë të mbrojtura aktualisht"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Trokit për të ndryshuar ose hequr fjalëkalimin për rezervime të plota të desktopit"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Çaktivizuar"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Gjithmonë aktive"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatike"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Zbatimi i WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Cakto zbatimin e WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Është çaktivizuar zbatimi i zgjedhur i WebView dhe duhet të aktivizohet për t\'u përdorur, dëshiron ta aktivizosh?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korrigjimi i ngjyrës"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ky funksion është eksperimental dhe mund të ndikojë në veprimtari."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Afërsisht <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Afërsisht <xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - afërsisht <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të jetë e plotë"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 002e963..8c47025 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Принудно дозволи апликације у спољној"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Омогућава уписивање свих апликација у спољну меморију, без обзира на вредности манифеста"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Принудно омогући промену величине активности"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Омогућава промену величине свих активности за режим са више прозора, без обзира на вредности манифеста."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Омогући промену величине свих активности за режим са више прозора, без обзира на вредности манифеста."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Омогући прозоре произвољног формата"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Омогућава подршку за експерименталне прозоре произвољног формата."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Омогућите подршку за експерименталне прозоре произвољног формата."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Лозинка резервне копије за рачунар"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Резервне копије читавог система тренутно нису заштићене"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Додирните да бисте променили или уклонили лозинку за прављење резервних копија читавог система на рачунару"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Онемогућено"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Увек укључено"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Аутоматски"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Примена WebView-а"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Подесите примену WebView-а"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Изабрана примена WebView-а је онемогућена, а мора да буде омогућена ради коришћења. Желите ли да је омогућите?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ова функција је експериментална и може да утиче на перформансе."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Још отприлике <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостало око <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Онемогућио је администратор"</string>
     <string name="home" msgid="8263346537524314127">"Почетни"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Пре <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Још <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 9b6f302..d25f9f5 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Tillåt appar i externt lagringsutrymme"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Appen kan skrivas till extern lagring, oavsett manifestvärden"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Framtvinga storleksanpassning för aktiviteter"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Detta gör det möjligt att ändra storleken på alla aktiviteter i flerfönsterläge, oavsett manifestvärden."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Gör det möjligt att ändra storleken på alla aktiviteter i flerfönsterläge, oavsett manifestvärden."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Aktivera frihandsfönster"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktiverar stöd för experimentella frihandsfönster."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktivera stöd för experimentella frihandsfönster."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Lösenord för säkerhetskopia av datorn"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"De fullständiga säkerhetskopiorna av datorn är för närvarande inte skyddade"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tryck om du vill ändra eller ta bort lösenordet för fullständig säkerhetskopiering av datorn"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Inaktiverad"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Alltid på"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatiskt"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Ange WebView-implementering"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Den valda WebView-implementeringen har inaktiverats och måste aktiveras om du ska kunna använda den. Vill du aktivera den?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Färgkorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Den här funktionen är experimentell och kan påverka prestandan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca <xliff:g id="TIME">%1$s</xliff:g> kvar"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Har inaktiverats av administratören"</string>
     <string name="home" msgid="8263346537524314127">"Startsida"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"för <xliff:g id="ID_1">%1$s</xliff:g> sedan"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> kvar"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index f9171ce..3f1d26a 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Lazima uruhusu programu kwenye hifadhi ya nje"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Huweka programu kwenye hifadhi ya nje, bila kujali maelezo"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Lazimisha shughuli ziweze kubadilishwa ukubwa"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Fanya shughuli zote ziweze kubadilishwa ukubwa kwa ajili ya dirisha nyingi, bila kujali thamani za faili ya maelezo."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Fanya shughuli zote ziweze kubadilishwa ukubwa kwenye madirisha mengi, bila kuzingatia thamani za faili ya maelezo."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Washa madirisha yenye muundo huru"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Huwasha uwezo wa kutumia madirisha ya majaribio yenye muundo huru."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Ruhusu uwezo wa kutumia madirisha ya majaribio yenye muundo huru."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Nenosiri la hifadhi rudufu ya eneo kazi"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Hifadhi rudufu kamili za eneo kazi hazijalindwa kwa sasa"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Gonga ili ubadilishe au uondoe nenosiri la hifadhi rudufu kamili za eneo kazi"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Imezimwa"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Imewashwa kila wakati"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Otomatiki"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Utekelezaji wa WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Weka utekelezaji wa WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Kipengee ulichochagua cha utekelezaji wa WebView kimezimwa. Ni lazima ukiwashe ili kitumike. Ungependa kukiwasha?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Usahihishaji wa rangi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Kipengele hiki ni cha majaribio na huenda kikaathiri utendaji."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zimesalia takribani <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takriban <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Msimamizi amezima mapendeleo ya mipangilio"</string>
     <string name="home" msgid="8263346537524314127">"Mwanzo"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"Zimepita <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Zimesalia <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index 56970a7..f06b0f9 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"பயன்பாடுகளை வெளிப்புறச் சேமிப்பிடத்தில் அனுமதி"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"மேனிஃபெஸ்ட் மதிப்புகளை பொருட்படுத்தாமல், எந்தப் பயன்பாட்டையும் வெளிப்புற சேமிப்பிடத்தில் எழுத அனுமதிக்கும்"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"செயல்பாடுகளை அளவுமாறக்கூடியதாக அமை"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"மேனிஃபெஸ்ட் மதிப்புகளைப் பொருட்படுத்தாமல், பல சாளரத்திற்கு எல்லா செயல்பாடுகளையும் அளவுமாறக்கூடியதாக அமைக்கும்."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"மேனிஃபெஸ்ட் மதிப்புகளைப் பொருட்படுத்தாமல், பல சாளரத்திற்கு எல்லா செயல்பாடுகளையும் அளவுமாறக்கூடியதாக அமை."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"குறிப்பிட்ட வடிவமில்லாத சாளரங்களை இயக்கு"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"பரிசோதனைக்குரிய குறிப்பிட்ட வடிவமில்லாத சாளரங்களுக்கான ஆதரவை இயக்கும்."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"சாளரங்களை அளவுமாற்ற மற்றும் எங்கும் நகர்த்த அனுமதிக்கும் பரிசோதனைக்குரிய அம்சத்திற்கான ஆதரவை இயக்கு."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"டெஸ்க்டாப் காப்புப்பிரதி கடவுச்சொல்"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"டெஸ்க்டாப்பின் முழு காப்புப்பிரதிகள் தற்போது பாதுகாக்கப்படவில்லை"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"டெஸ்க்டாப்பின் முழுக் காப்புப் பிரதிகளுக்கான கடவுச்சொல்லை மாற்ற அல்லது அகற்ற, தட்டவும்"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"முடக்கப்பட்டது"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"எப்போதும் இயக்கத்தில் வை"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"தானியங்கு"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView செயல்படுத்தல்"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView செயல்படுத்தலை அமை"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"தேர்வுசெய்த WebView செயல்படுத்தல் முடக்கப்பட்டுள்ளது, பயன்படுத்த வேண்டுமெனில் அதைக் கண்டிப்பாக இயக்க வேண்டும். இயக்க விரும்புகிறீர்களா?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"வண்ணத்திருத்தம்"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"தோராயமாக <xliff:g id="TIME">%1$s</xliff:g> உள்ளது"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"தோராயம்: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> உள்ளது"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"முழு சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"நிர்வாகி முடக்கியுள்ளார்"</string>
     <string name="home" msgid="8263346537524314127">"முகப்பு"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> முன்"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> உள்ளது"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index 5a8c824..e6d594b 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"అనువర్తనాలను బాహ్య నిల్వలో నిర్బంధంగా అనుమతించు"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ఏ అనువర్తనాన్ని అయినా మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా బాహ్య నిల్వలో వ్రాయగలిగేలా అనుమతిస్తుంది"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"కార్యాచరణలను పరిమాణం మార్చగలిగేలా నిర్బంధించు"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా అన్ని కార్యాచరణలను బహుళ విండోల్లో సరిపోయేటట్లు పరిమాణం మార్చగలిగేలా చేస్తుంది."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా అన్ని కార్యాచరణలను పలు రకాల విండోల్లో సరిపోయేట్లు పరిమాణం మార్చగలిగేలా చేస్తుంది."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"స్వతంత్ర రూప విండోలను ప్రారంభించండి"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"ప్రయోగాత్మక స్వతంత్ర రూప విండోలకు మద్దతును ప్రారంభిస్తుంది."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ప్రయోగాత్మక స్వతంత్ర రూప విండోల కోసం మద్దతును ప్రారంభిస్తుంది."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"డెస్క్‌టాప్ బ్యాకప్ పాస్‌వర్డ్"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"డెస్క్‌టాప్ పూర్తి బ్యాకప్‌లు ప్రస్తుతం రక్షించబడలేదు"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"డెస్క్‌టాప్ పూర్తి బ్యాకప్‌ల కోసం పాస్‌వర్డ్‌ను మార్చడానికి లేదా తీసివేయడానికి నొక్కండి"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"నిలిపివేయబడింది"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"ఎల్లప్పుడూ ఆన్‌లో ఉంచు"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"స్వయంచాలకం"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"వెబ్ వీక్షణ అమలు"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"వెబ్ వీక్షణ అమలుని సెట్ చేయండి"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"ఎంచుకున్న వెబ్ వీక్షణ అమలు నిలిపివేయబడింది, కానీ ఉపయోగించడానికి తప్పనిసరిగా ప్రారంభించాల్సి ఉంటుంది, మీరు దీన్ని ప్రారంభించాలనుకుంటున్నారా?"</string>
@@ -296,7 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"రంగు సవరణ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"సుమారు <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"సుమారు <xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - సుమారు <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 5ef3168..ab428a9 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"บังคับให้แอปสามารถใช้ที่เก็บภายนอก"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"ให้สามารถเขียนแอปต่างๆ ไปยังที่เก็บภายนอกได้ โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"บังคับให้กิจกรรมปรับขนาดได้"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"ทำให้กิจกรรมทั้งหมดปรับขนาดได้สำหรับหน้าต่างหลายบาน โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ทำให้กิจกรรมทั้งหมดปรับขนาดได้สำหรับหน้าต่างหลายบาน โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"เปิดใช้หน้าต่างรูปแบบอิสระ"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"เปิดการสนับสนุนหน้าต่างรูปแบบอิสระแบบทดลอง"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"เปิดการสนับสนุนหน้าต่างรูปแบบอิสระแบบทดลอง"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"รหัสผ่านการสำรองข้อมูลในเดสก์ท็อป"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"การสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อป ไม่ได้รับการป้องกันในขณะนี้"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"แตะเพื่อเปลี่ยนแปลงหรือลบรหัสผ่านสำหรับการสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อป"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"ปิดใช้แล้ว"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"เปิดใช้เสมอ"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"อัตโนมัติ"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"การใช้งาน WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"ตั้งค่าการใช้งาน WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"การใช้งาน WebView ที่เลือกไว้ถูกปิดใช้อยู่ คุณต้องการเปิดใช้เพื่อที่จะใช้งานไหม"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"การแก้สี"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"คุณลักษณะนี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"เหลืออีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็ม"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"ปิดใช้โดยผู้ดูแลระบบ"</string>
     <string name="home" msgid="8263346537524314127">"หน้าแรก"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>ที่ผ่านมา"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"เหลือ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 8a7d6aa..b21acda 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Pwersahang payagan ang mga app sa external"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Mara-write na sa external storage ang anumang app, anuman ang manifest value"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Sapilitang gawing resizable ang mga aktibidad"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Gawing resizable para sa multi-window ang lahat ng aktibidad, anuman ang mga manifest value."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Gawing nare-resize ang lahat ng aktibidad para sa multi-window, anuman ang mga value ng manifest."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"I-enable ang mga freeform window"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ine-enable ang suporta para sa mga pang-eksperimentong freeform window."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"I-enable ang suporta para sa mga pang-eksperimentong freeform window."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Password ng pag-backup ng desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Kasalukuyang hindi pinoprotektahan ang mga buong pag-backup ng desktop"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"I-tap upang baguhin o alisin ang password para sa mga kumpletong pag-back up sa desktop"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Naka-disable"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Palaging naka-on"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Awtomatiko"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Pagpapatupad sa WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Itakda ang pagpapatupad sa WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Naka-disable ang napiling pagpapatupad sa WebView, at dapat itong i-enable upang magamit, gusto mo ba itong i-enable?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pagtatama ng kulay"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ang feature na ito ay pinag-eeksperimentuhan at maaaring makaapekto sa pagganap."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> na lang ang natitira"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit kumulang <xliff:g id="TIME">%2$s</xliff:g> ang natitira"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Na-disable ng administrator"</string>
     <string name="home" msgid="8263346537524314127">"Home"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> na ang nakalipas"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> na lang"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 11b975e..beca481 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Harici birimdeki uygulamalara izin vermeye zorla"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Bildirilen değerlerden bağımsız olarak uygulamaları harici depolamaya yazmak için uygun hale getirir"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Etkinlikleri yeniden boyutlandırılabilmeye zorla"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Manifest değerlerinden bağımsız olarak, tüm etkinlikleri birden fazla pencerede yeniden boyutlandırılabilir hale getirir."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Manifest değerlerinden bağımsız olarak, tüm etkinlikleri birden fazla pencerede yeniden boyutlandırılabilir yap."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Serbest biçimli pencereleri etkinleştir"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Deneysel serbest biçimli pencereleri etkinleştirir."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Deneysel serbest biçimli pencere desteğini etkinleştir."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Masaüstü yedekleme şifresi"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Masaüstü tam yedeklemeleri şu an korunmuyor"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Masaüstü tam yedeklemelerinin şifresini değiştirmek veya kaldırmak için hafifçe dokunun"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Devre dışı"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Her zaman açık"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Otomatik"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView kullanımı"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView kullanımını ayarla"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Seçilen WebView uygulama şekli devre dışı. Bu uygulama şeklinin kullanılabilmesi için etkinleştirilmesi gerekir. Etkinleştirmek istiyor musunuz?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Renk düzeltme"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu özellik deneyseldir ve performansı etkileyebilir."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Yönetici tarafından devre dışı bırakıldı"</string>
     <string name="home" msgid="8263346537524314127">"Ana Ekran"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> önce"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> kaldı"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index ad18d7f..9250dfd 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Примусово записувати додатки в зовнішню пам’ять"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Додатки можна записувати на зовнішню пам’ять незалежно від значень маніфесту"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Примусово масштабувати активність"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Активність масштабуватиметься на кілька вікон, незалежно від значень у файлі маніфесту."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Масштабувати активність на кілька вікон, незалежно від значень у файлі маніфесту."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Увімкнути вікна довільного формату"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Увімкнуться експериментальні вікна довільного формату."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Увімкнути експериментальні вікна довільного формату."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Пароль резерв.копії на ПК"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Повні резервні копії на комп’ютері наразі не захищені"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Торкніться, щоб змінити або видалити пароль для повного резервного копіювання на комп’ютер"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Вимкнено"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Завжди ввімкнено"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Автоматично"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Застосування WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Налаштувати застосування WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Вибране застосування WebView вимкнено. Увімкнути його?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекція кольору"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Це експериментальна функція. Вона може вплинути на продуктивність."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Залишилося приблизно <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилось близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Вимкнено адміністратором"</string>
     <string name="home" msgid="8263346537524314127">"Головний екран"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> тому"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Залишилося <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index 670f2e6..3173b33 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"بیرونی پر ایپس کو زبردستی اجازت دیں"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"‏manifest اقدار سے قطع نظر، کسی بھی ایپ کو بیرونی اسٹوریج پر لکھے جانے کا اہل بناتا ہے"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"سرگرمیوں کو ری سائز ایبل بنائیں"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"‏manifest اقدار سے قطع نظر، ملٹی ونڈو کیلئے تمام سرگرمیوں کو ری سائز ایبل بناتا ہے۔"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"‏manifest اقدار سے قطع نظر، ملٹی ونڈو کیلئے تمام سرگرمیوں کو ری سائز ایبل بنائیں۔"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"‏freeform ونڈوز فعال کریں"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"‏تجرباتی freeform ونڈوز کے لئے سپورٹ فعال کرتا ہے۔"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"‏تجرباتی freeform ونڈوز کیلئے سپورٹ فعال کریں۔"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ڈیسک ٹاپ کا بیک اپ پاس ورڈ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ڈیسک ٹاپ کے مکمل بیک اپس فی الحال محفوظ کیے ہوئے نہیں ہیں"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ڈیسک ٹاپ کے مکمل بیک اپس کیلئے پاس ورڈ کو تبدیل کرنے یا ہٹانے کیلئے تھپتھپائیں"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"غیر فعال"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"ہمیشہ آن"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"خودکار"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"‏WebView کا نفاذ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"‏WebView کا نفاذ سیٹ کریں"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"‏منتخب کردہ WebView کا نفاذ غیر فعال ہے اور استعمال کرنے کیلئے اسے فعال ہونا چاہئیے، کیا آپ اسے فعال کرنا چاہتے ہیں؟"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"رنگ کی اصلاح"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"یہ خصوصیت تجرباتی ہے اور اس کی وجہ سے کاکردگی متاثر ہو سکتی ہے۔"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریبا <xliff:g id="TIME">%1$s</xliff:g> باقی ہیں"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g>‎ - تقریبا <xliff:g id="TIME">%2$s</xliff:g> باقی"</string>
     <string name="power_charging" msgid="1779532561355864267">"‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>‎"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>‎ پورا ہونے تک"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"منتظم نے غیر فعال کر دیا"</string>
     <string name="home" msgid="8263346537524314127">"ہوم"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> قبل"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> باقی ہیں"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index e7dccae..d6d8207 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Tashqi xotira qurilmasidagi ilova dasturlariga majburiy ruxsat berish"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Manifest qiymatidan qat’i nazar istalgan ilovani tashqi xotiraga saqlash imkonini beradi"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Harakatlarni moslashuvchan o‘lchamga keltirish"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Manifest qiymatidan qat’i nazar barcha harakatlarni ko‘p oynali rejimga moslashtiradi."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Manifest qiymatidan qat’i nazar barcha harakatlarni ko‘p oynali rejimga moslashtirish."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Erkin shakldagi oynalarni yoqish"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Tajribaviy erkin shakldagi oynalar ta’minotini yoqadi"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Tajribaviy erkin shakldagi oynalar ta’minotini yoqish."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Zaxira nusxa uchun parol"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Kompyuterdagi zaxira nusxalar hozirgi vaqtda himoyalanmagan"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ish stoli to‘liq zaxira nusxalari parolini o‘zgartirish yoki o‘chirish uchun bu yerni bosing"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"O‘chiq"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Har doim yoniq tursin"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Avtomatik"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ta’minotchisi"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView ta’minotchisini sozlash"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Tanlangan WebView ta’minotchisi o‘chirilgan va foydalanish uchun yoqilishi zarur. Yoqilsinmi?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rangni tuzatish"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, to‘lguncha"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Administrator tomonidan o‘chirib qo‘yilgan"</string>
     <string name="home" msgid="8263346537524314127">"Bosh ekran"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> oldin"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> qoldi"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index c803415..5cc34bb 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Buộc cho phép các ứng dụng trên bộ nhớ ngoài"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Giúp ứng dụng bất kỳ đủ điều kiện được ghi vào bộ nhớ ngoài bất kể giá trị tệp kê khai là gì"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Buộc các hoạt động có thể thay đổi kích thước"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Giúp tất cả hoạt động có thể thay đổi kích thước cho nhiều cửa sổ bất kể giá trị tệp kê khai là gì."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Giúp tất cả hoạt động có thể thay đổi kích thước cho nhiều cửa sổ bất kể giá trị tệp kê khai là gì."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Bật cửa sổ dạng tự do"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Bật tính năng hỗ trợ cửa sổ dạng tự do thử nghiệm."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Bật tính năng hỗ trợ cửa sổ dạng tự do thử nghiệm."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Mật khẩu sao lưu của máy tính"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Sao lưu toàn bộ máy tính hiện không được bảo vệ"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Nhấn để thay đổi hoặc xóa mật khẩu dành cho sao lưu toàn bộ tới máy tính"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Đã tắt"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Luôn bật"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Tự động"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Triển khai WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Đặt triển khai WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Triển khai WebView đã chọn bị vô hiệu hóa và bạn phải bật để sử dụng tính năng này. Bạn có muốn bật tính năng này không?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Sửa màu"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tính năng này là tính năng thử nghiệm và có thể ảnh hưởng đến hoạt động."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Bị tắt bởi quản trị viên"</string>
     <string name="home" msgid="8263346537524314127">"Màn hình chính"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> trước"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Còn <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 54a6e7c..4b67322 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -248,9 +248,11 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"强制允许将应用写入外部存储设备"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"允许将任何应用写入外部存储设备(无论清单值是什么)"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"强制将活动设为可调整大小"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"将所有活动设为可配合多窗口环境调整大小(无论清单值是什么)。"</string>
+    <!-- no translation found for force_resizable_activities_summary (6667493494706124459) -->
+    <skip />
     <string name="enable_freeform_support" msgid="1461893351278940416">"启用可自由调整的窗口"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"启用可自由调整的窗口这一实验性功能。"</string>
+    <!-- no translation found for enable_freeform_support_summary (8247310463288834487) -->
+    <skip />
     <string name="local_backup_password_title" msgid="3860471654439418822">"桌面备份密码"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"桌面完整备份当前未设置密码保护"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"点按即可更改或移除用于保护桌面完整备份的密码"</string>
@@ -277,6 +279,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"已停用"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"始终开启"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"自动"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView 实现"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"设置 WebView 实现"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"所选的 WebView 实现已停用,您必须先启用 WebView 实现才能加以使用。要启用该 WebView 实现吗?"</string>
@@ -296,8 +302,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"此功能为实验性功能,可能会影响性能。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"还剩大约 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用大约<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string>
@@ -314,8 +319,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"已被管理员禁用"</string>
     <string name="home" msgid="8263346537524314127">"主屏幕"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"还剩 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index e95a324..301b90b 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"強制允許應用程式寫入到外部儲存空間"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"允許將所有應用程式寫入到外部儲存完間 (所有資訊清單值)"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"強制可變更活動尺寸"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"在任何資訊清單值下,允許為多個視窗變更所有活動的尺寸。"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"在任何資訊清單值下,允許系統配合多重視窗環境調整所有活動的尺寸。"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"啟用自由形態視窗"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"啟用實驗版自由形態視窗的支援功能。"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"啟用實驗版自由形態視窗的支援功能。"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"桌面電腦備份密碼"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"桌上電腦的完整備份目前未受保護"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"輕按即可變更或移除桌上電腦完整備份的密碼"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"已停用"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"永遠開啟"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"自動"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView 設置"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"設定 WebView 設置"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"您選擇的 WebView 設定已停用,您必須先啟用此設定才能加以使用。要啟用此設定嗎?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會影響效能。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"尚餘大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"管理員已停用此設定"</string>
     <string name="home" msgid="8263346537524314127">"主畫面"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"尚餘 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index bf7ea4e..ce8303c 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"強制允許將應用程式寫入外部儲存空間"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"允許將任何應用程式寫入外部儲存空間 (無論資訊清單值為何)"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"將活動強制設為可調整大小"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"將所有活動設為可配合多重視窗環境調整大小 (無論資訊清單值為何)。"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"將所有活動設為可配合多重視窗環境調整大小 (無論資訊清單值為何)。"</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"啟用自由形式視窗"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"啟用實驗版自由形式視窗的支援功能。"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"啟用實驗版自由形式視窗的支援功能。"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"電腦備份密碼"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"電腦完整備份目前未受保護"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"輕按即可變更或移除電腦完整備份的密碼"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"已停用"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"一律開啟"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"自動"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView 實作"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"設定 WebView 實作"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"您所選的 WebView 實作已停用,您必須先啟用 WebView 實作才能加以使用。要啟用該 WebView 實作嗎?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會對效能造成影響。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"還剩大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大約還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"已由管理員停用"</string>
     <string name="home" msgid="8263346537524314127">"主畫面"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"還剩 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index c450f77..149011a 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -248,9 +248,9 @@
     <string name="force_allow_on_external" msgid="3215759785081916381">"Phoqelela ukuvumela izinhlelo zokusebenza ngaphandle"</string>
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Yenza noma uluphi uhlelo lokusebenza lifaneleke ukuthi libhalwe kusitoreji sangaphandle, ngaphandle kwamavelu we-manifest"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Imisebenzi yamandla izonikezwa usayizi omusha"</string>
-    <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Yenza yonke imisebenzi ibe nosayizi abasha kuwindi lokuningi, ngokunganaki amanani we-manifest."</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Yenza yonke imisebenzi ibe nosayizi abasha kumawindi amaningi, ngokunganaki amavelu e-manifest."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Nika amandla amawindi e-freeform"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Inika amandla usekelo lwamawindi okuhlola e-freeform."</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Nika amandla usekelo lwe-windows yokuhlola kwe-freeform."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Iphasiwedi yokusekela ngokulondoloza ye-Desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Ukusekela ngokulondoloza okugcwele kwe-Desktop akuvikelekile okwamanje."</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Thepha ukushintsha noma ukususa iphasiwedi yokwenziwa kwezipele ngokugcwele kwideskithophu"</string>
@@ -277,6 +277,10 @@
     <string name="night_mode_no" msgid="9171772244775838901">"Kukhutshaziwe"</string>
     <string name="night_mode_yes" msgid="2218157265997633432">"Njalo ivuliwe"</string>
     <string name="night_mode_auto" msgid="7508348175804304327">"Okuzenzakalelayo"</string>
+    <!-- no translation found for enable_webview_multiprocess (3405948012467585908) -->
+    <skip />
+    <!-- no translation found for enable_webview_multiprocess_desc (852226124223847283) -->
+    <skip />
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Ukufakwa ke-WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Sesba ukufakwa kwe-WebView"</string>
     <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Ukusetshenziswa kwe-WebView okukhethiwe kukhutshaziwe, futhi kuzomele kunikwe amandla ukuze kusetshenziswe, ingabe ufisa ukukunika amandla?"</string>
@@ -296,8 +300,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ukulungiswa kombala"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Lesi sici esesilingo futhi singathinta ukusebenza."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
-    <skip />
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Cishe ngu-<xliff:g id="TIME">%1$s</xliff:g> osele"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - isilinganiso esingu-<xliff:g id="TIME">%2$s</xliff:g> esisele"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale"</string>
@@ -314,8 +317,6 @@
     <string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Ikhutshazwe umlawuli"</string>
     <string name="home" msgid="8263346537524314127">"Ekhaya"</string>
-    <!-- no translation found for charge_length_format (8978516217024434156) -->
-    <skip />
-    <!-- no translation found for remaining_length_format (7886337596669190587) -->
-    <skip />
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> edlule"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> osele"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 654b398..57c5684 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -778,7 +778,7 @@
     <string name="battery_info_status_full">Full</string>
 
     <!-- Summary for settings preference disabled by administrator [CHAR LIMIT=50] -->
-    <string name="disabled_by_admin_summary_text">Disabled by administrator</string>
+    <string name="disabled_by_admin_summary_text">Controlled by admin</string>
 
     <!-- Option in navigation drawer that leads to Settings main screen [CHAR LIMIT=30] -->
     <string name="home">Home</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index c44b638..6d29c5f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -113,6 +113,12 @@
         return admin;
     }
 
+    public static boolean hasBaseUserRestriction(Context context,
+            String userRestriction, int userId) {
+        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        return um.hasBaseUserRestriction(userRestriction, UserHandle.of(userId));
+    }
+
     /**
      * Checks if keyguard features are disabled by policy.
      *
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 9bd4eb1..227b1e8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -70,6 +70,12 @@
                 }
             }
             mAttrUserRestriction = data == null ? null : data.toString();
+            // If the system has set the user restriction, then we shouldn't add the padlock.
+            if (RestrictedLockUtils.hasBaseUserRestriction(mContext, mAttrUserRestriction,
+                    UserHandle.myUserId())) {
+                mAttrUserRestriction = null;
+                return;
+            }
 
             final TypedValue useAdminDisabledSummary =
                     attributes.peekValue(R.styleable.RestrictedPreference_useAdminDisabledSummary);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 7416fb5..5b865f9 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -40,6 +40,7 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
     <!-- System tool permissions granted to the shell. -->
     <uses-permission android:name="android.permission.REAL_GET_TASKS" />
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
@@ -109,6 +110,7 @@
     <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
 
     <application android:label="@string/app_label"
                  android:forceDeviceEncrypted="true"
diff --git a/packages/SystemUI/res/drawable/ic_colorize.xml b/packages/SystemUI/res/drawable/ic_night_mode.xml
similarity index 95%
rename from packages/SystemUI/res/drawable/ic_colorize.xml
rename to packages/SystemUI/res/drawable/ic_night_mode.xml
index 79fd6d9..caa7a47 100644
--- a/packages/SystemUI/res/drawable/ic_colorize.xml
+++ b/packages/SystemUI/res/drawable/ic_night_mode.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2015 The Android Open Source Project
+    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.
diff --git a/packages/SystemUI/res/drawable/ic_colorize.xml b/packages/SystemUI/res/drawable/ic_night_mode_disabled.xml
similarity index 91%
copy from packages/SystemUI/res/drawable/ic_colorize.xml
copy to packages/SystemUI/res/drawable/ic_night_mode_disabled.xml
index 79fd6d9..010815a 100644
--- a/packages/SystemUI/res/drawable/ic_colorize.xml
+++ b/packages/SystemUI/res/drawable/ic_night_mode_disabled.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2015 The Android Open Source Project
+    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.
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
+        android:fillColor="#4DFFFFFF"
         android:pathData="M20.71,5.63l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0.0l-3.12,3.12 -1.93,-1.91 -1.41,1.41 1.42,1.42L3.0,16.25L3.0,21.0l4.75,0.0l8.92,-8.92 1.42,1.42 1.41,-1.41 -1.92,-1.92 3.12,-3.12c0.4,0.0 0.4,-1.0 0.01,-1.42zM6.92,19.0L5.0,17.08l8.06,-8.06 1.92,1.92L6.92,19.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout/preference_matrix.xml b/packages/SystemUI/res/layout/calibrate_sliders.xml
similarity index 93%
rename from packages/SystemUI/res/layout/preference_matrix.xml
rename to packages/SystemUI/res/layout/calibrate_sliders.xml
index 1f6066e..0dec8a1 100644
--- a/packages/SystemUI/res/layout/preference_matrix.xml
+++ b/packages/SystemUI/res/layout/calibrate_sliders.xml
@@ -94,11 +94,4 @@
             android:layout_weight="1" />
     </LinearLayout>
 
-    <Button
-        android:id="@+id/apply"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end"
-        android:text="@string/color_apply" />
-
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/color_matrix_settings.xml b/packages/SystemUI/res/layout/night_mode_settings.xml
similarity index 100%
rename from packages/SystemUI/res/layout/color_matrix_settings.xml
rename to packages/SystemUI/res/layout/night_mode_settings.xml
diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml
index e550d9c..4d0eb96 100644
--- a/packages/SystemUI/res/layout/notification_guts.xml
+++ b/packages/SystemUI/res/layout/notification_guts.xml
@@ -126,27 +126,6 @@
                     android:tint="@color/notification_guts_icon_tint" />
 
         </FrameLayout>
-
-        <RadioGroup
-                    android:id="@+id/apply_to"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content" >
-            <RadioButton android:id="@+id/apply_to_topic"
-                         android:layout_width="wrap_content"
-                         android:layout_height="48dp"
-                         style="@style/TextAppearance.NotificationGuts.Primary"
-                         android:visibility="gone"
-                         android:buttonTint="#858383"
-            />
-            <RadioButton android:id="@+id/apply_to_app"
-                         android:layout_width="wrap_content"
-                         android:layout_height="48dp"
-                         android:text="@string/apply_to_app"
-                         style="@style/TextAppearance.NotificationGuts.Primary"
-                         android:visibility="gone"
-                         android:buttonTint="#858383"
-            />
-        </RadioGroup>
     </LinearLayout>
     <!-- buttons -->
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/notification_settings_icon_row.xml b/packages/SystemUI/res/layout/notification_settings_icon_row.xml
new file mode 100644
index 0000000..52d07fc
--- /dev/null
+++ b/packages/SystemUI/res/layout/notification_settings_icon_row.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright 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.
+-->
+<com.android.systemui.statusbar.NotificationSettingsIconRow
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    >
+
+    <com.android.systemui.statusbar.AlphaOptimizedImageView
+        android:id="@+id/gear_icon"
+        android:layout_width="@dimen/notification_gear_width"
+        android:layout_height="@dimen/notification_gear_height"
+        android:paddingTop="@dimen/notification_gear_top_padding"
+        android:paddingStart="@dimen/notification_gear_padding"
+        android:paddingEnd="@dimen/notification_gear_padding"
+        android:paddingBottom="@dimen/notification_gear_padding"
+        android:src="@drawable/ic_settings"
+        android:tint="@color/notification_gear_color"
+        android:visibility="invisible"
+        android:alpha="0"
+        android:background="?android:attr/selectableItemBackgroundBorderless"
+        />
+
+</com.android.systemui.statusbar.NotificationSettingsIconRow>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_paged_page.xml b/packages/SystemUI/res/layout/qs_paged_page.xml
index eef08ba..a246e0d 100644
--- a/packages/SystemUI/res/layout/qs_paged_page.xml
+++ b/packages/SystemUI/res/layout/qs_paged_page.xml
@@ -19,4 +19,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/tile_page"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content" />
+    android:layout_height="wrap_content"
+    android:clipChildren="false"
+    android:clipToPadding="false" />
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index c23c745..9dd3ad2 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -18,12 +18,14 @@
 <com.android.systemui.qs.PagedTileLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:clipChildren="false"
+    android:clipToPadding="false">
 
     <FrameLayout
         android:id="@+id/page_decor"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_height="48dp"
         android:layout_gravity="bottom">
 
         <com.android.systemui.qs.PageIndicator
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 9f90af2..b8f10db 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -26,7 +26,9 @@
             android:layout_marginTop="@dimen/status_bar_header_height"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:paddingBottom="8dp" />
+            android:paddingBottom="8dp"
+            android:clipToPadding="false"
+            android:clipChildren="false" />
 
     <include layout="@layout/quick_status_bar_expanded_header" />
 
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 62fdd42..c4c45bb 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -23,6 +23,14 @@
     android:clickable="true"
     >
 
+    <ViewStub
+        android:layout="@layout/notification_settings_icon_row"
+        android:id="@+id/settings_icon_row_stub"
+        android:inflatedId="@+id/notification_settings_icon_row"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        />
+
     <com.android.systemui.statusbar.NotificationBackgroundView
         android:id="@+id/backgroundNormal"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4cd920a..8f69bbb 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -102,6 +102,9 @@
     <!-- The color of the circle around the primary user in the user switcher -->
     <color name="current_user_border_color">@color/system_accent_color</color>
 
+    <!-- The color of the gear shown behind a notification -->
+    <color name="notification_gear_color">#ff757575</color>
+
     <!-- The "inside" of a notification, reached via longpress -->
     <color name="notification_guts_bg_color">#eeeeee</color>
     <color name="notification_guts_slider_color">@*android:color/material_deep_teal_500</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b8044ba..ee61e00 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -58,7 +58,7 @@
     <item name="status_bar_icon_scale_factor" format="float" type="dimen">1.0</item>
 
     <!-- Height of a small notification in the status bar-->
-    <dimen name="notification_min_height">84dp</dimen>
+    <dimen name="notification_min_height">86dp</dimen>
 
     <!-- Height of a small notification in the status bar which was used before android N -->
     <dimen name="notification_min_height_legacy">64dp</dimen>
@@ -78,6 +78,18 @@
     <!-- Minimum layouted height of a notification in the statusbar-->
     <dimen name="min_notification_layout_height">48dp</dimen>
 
+    <!-- Width of the space containing the gear icon behind a notification -->
+    <dimen name="notification_gear_width">64dp</dimen>
+
+    <!-- Height of the space containing the gear icon behind a notification -->
+    <dimen name="notification_gear_height">74dp</dimen>
+
+    <!-- The space above the gear icon displayed behind a notification -->
+    <dimen name="notification_gear_top_padding">30dp</dimen>
+
+    <!-- The space on either side and below the gear icon displayed behind a notification  -->
+    <dimen name="notification_gear_padding">20dp</dimen>
+
     <!-- size at which Notification icons will be drawn in the status bar -->
     <dimen name="status_bar_icon_drawing_size">17dip</dimen>
 
@@ -166,7 +178,7 @@
     <dimen name="qs_date_alarm_anim_translation">26dp</dimen>
     <dimen name="qs_date_collapsed_text_size">14sp</dimen>
     <dimen name="qs_date_text_size">16sp</dimen>
-    <dimen name="qs_header_gear_translation">120dp</dimen>
+    <dimen name="qs_header_gear_translation">150dp</dimen>
     <dimen name="qs_page_indicator_size">12dp</dimen>
     <dimen name="qs_tile_icon_size">24dp</dimen>
     <dimen name="qs_tile_text_size">12sp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6135dc6..0bd7c4e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1234,29 +1234,43 @@
     <!-- Notification: Control panel: Label for button that dismisses control panel. [CHAR LIMIT=NONE] -->
     <string name="notification_done">Done</string>
 
-    <!-- Label for no color transform [CHAR LIMIT=30] -->
-    <string name="color_matrix_none">Normal colors</string>
+    <!-- SysUI Tuner: Color and appearance screen title [CHAR LIMIT=50] -->
+    <string name="color_and_appearance">Color and appearance</string>
 
-    <!-- Label for night color transform [CHAR LIMIT=30] -->
-    <string name="color_matrix_night">Night colors</string>
+    <!-- SysUI Tuner: Name of the night mode feature [CHAR LIMIT=30] -->
+    <string name="night_mode">Night mode</string>
 
-    <!-- Label for custom color transform [CHAR LIMIT=30] -->
-    <string name="color_matrix_custom">Custom colors</string>
+    <!-- SysUI Tuner: Name of calibrate display dialog [CHAR LIMIT=30] -->
+    <string name="calibrate_display">Calibrate display</string>
 
-    <!-- Label for auto color transforms [CHAR LIMIT=30] -->
-    <string name="color_matrix_auto">Auto</string>
+    <!-- SysUI Tuner: Summary of night mode when its on [CHAR LIMIT=NONE] -->
+    <string name="night_mode_on">On</string>
 
-    <!-- Label for unknown color transform [CHAR LIMIT=30] -->
-    <string name="color_matrix_unknown">Unknown colors</string>
+    <!-- SysUI Tuner: Summary of night mode when its off [CHAR LIMIT=NONE] -->
+    <string name="night_mode_off">Off</string>
 
-    <!-- Title for color transform [CHAR LIMIT=30] -->
-    <string name="color_transform">Color modification</string>
+    <!-- SysUI Tuner: Label for switch to turn on night mode automatically [CHAR LIMIT=50] -->
+    <string name="turn_on_automatically">Turn on automatically</string>
 
-    <!-- Title for setting to show Quick Settings tile [CHAR LIMIT=60] -->
-    <string name="color_matrix_show_qs">Show Quick Settings tile</string>
+    <!-- SysUI Tuner: Summary for switch to turn on night mode automatically [CHAR LIMIT=NONE] -->
+    <string name="turn_on_auto_summary">Switch into Night Mode as appropriate for location and time of day</string>
 
-    <!-- Title for switch to enable custom color transform [CHAR LIMIT=60] -->
-    <string name="color_enable_custom">Enable custom transform</string>
+    <!-- SysUI Tuner: Label for section controlling what night mode does [CHAR LIMIT=60] -->
+    <string name="when_night_mode_on">When Night Mode is on</string>
+
+    <!-- SysUI Tuner: Switch controlling whether dark theme is turned on with night mode [CHAR LIMIT=45] -->
+    <string name="use_dark_theme">Use dark theme for Android OS</string>
+
+    <!-- SysUI Tuner: Switch controlling whether tint is changed with night mode [CHAR LIMIT=45] -->
+    <string name="adjust_tint">Adjust tint</string>
+
+    <!-- SysUI Tuner: Switch controlling whether brightness is changed with night mode [CHAR LIMIT=45] -->
+    <string name="adjust_brightness">Adjust brightness</string>
+
+    <!-- SysUI Tuner: Disclaimer about using dark theme with night mode [CHAR LIMIT=NONE] -->
+    <string name="night_mode_disclaimer">The dark theme is applied to
+        core areas of Android OS that are normally displayed in a light theme,
+        such as Settings and notifications.</string>
 
     <!-- Button to apply settings [CHAR LIMIT=30] -->
     <string name="color_apply">Apply</string>
@@ -1295,15 +1309,14 @@
     <string name="keyboard_shortcut_group_system_back">Back</string>
 
     <!-- SysUI Tuner: Option to show full do not disturb panel in volume [CHAR LIMIT=60] -->
-    <string name="tuner_full_zen_title">Show do not disturb in volume</string>
-    <!-- SysUI Tuner: Summary of option to show full do not disturb panel in volume [CHAR LIMIT=NONE] -->
-    <string name="tuner_full_zen_summary">Allow full control of do not disturb in the volume dialog.</string>
+    <string name="tuner_full_zen_title">Show with volume controls</string>
 
-    <!-- SysUI Tuner: Label for screen about volume and do not disturb settings [CHAR LIMIT=60] -->
-    <string name="volume_and_do_not_disturb">Volume and Do not disturb</string>
+    <!-- SysUI Tuner: Label for screen about do not disturb settings [CHAR LIMIT=60] -->
+    <string name="volume_and_do_not_disturb">Do not disturb</string>
 
-    <!-- SysUI Tuner: Switch to control volume down behavior [CHAR LIMIT=60] -->
-    <string name="volume_down_silent">Enter do not disturb on volume down</string>
+    <!-- SysUI Tuner: Switch to control whether volume buttons enter/exit do
+         not disturb [CHAR LIMIT=60] -->
+    <string name="volume_dnd_silent">Volume buttons shortcut</string>
 
     <!-- SysUI Tuner: Switch to control volume up behavior [CHAR LIMIT=60] -->
     <string name="volume_up_silent">Exit do not disturb on volume up</string>
@@ -1323,9 +1336,6 @@
     <!-- Accessibility description of headset icon [CHAR LIMIT=NONE] -->
     <string name="accessibility_status_bar_headset">Headset connected</string>
 
-    <!-- Explanation of the status bar section of the tuner [CHAR LIMIT=NONE] -->
-    <string name="tuner_status_bar_explanation">Enable or disable icons from being shown in the status bar.</string>
-
     <!-- Label for quick settings tile for data saver [CHAR LIMIT=30] -->
     <string name="data_saver">Data Saver</string>
 
@@ -1338,6 +1348,9 @@
     <!-- Label for feature switch [CHAR LIMIT=30] -->
     <string name="switch_bar_on">On</string>
 
+    <!-- Label for feature switch [CHAR LIMIT=30] -->
+    <string name="switch_bar_off">Off</string>
+
     <!-- SysUI Tuner: Button that leads to the navigation bar customization screen [CHAR LIMIT=60] -->
     <string name="nav_bar">Navigation bar</string>
 
@@ -1398,4 +1411,21 @@
     <!-- Button to edit the tile ordering of quick settings [CHAR LIMIT=60] -->
     <string name="qs_edit">Edit</string>
 
+    <!-- SysUI Tuner: Options for how clock is displayed [CHAR LIMIT=NONE] -->
+    <string name="tuner_time">Time</string>
+
+    <!-- SysUI Tuner: Options for how clock is displayed [CHAR LIMIT=NONE] -->
+    <string-array name="clock_options">
+        <item>Show hours, minutes, and seconds</item>
+        <item>Show hours and minutes (default)</item>
+        <item>Don\'t show this icon</item>
+    </string-array>
+
+    <!-- SysUI Tuner: Options for how battery is displayed [CHAR LIMIT=NONE] -->
+    <string-array name="battery_options">
+        <item>Always show percentage</item>
+        <item>Show percentage when charging (default)</item>
+        <item>Don\'t show this icon</item>
+    </string-array>
+
 </resources>
diff --git a/packages/SystemUI/res/xml/color_and_appearance.xml b/packages/SystemUI/res/xml/color_and_appearance.xml
new file mode 100644
index 0000000..21f890e
--- /dev/null
+++ b/packages/SystemUI/res/xml/color_and_appearance.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
+    android:title="@string/color_and_appearance">
+
+    <Preference
+        android:key="night_mode"
+        android:title="@string/night_mode"
+        android:fragment="com.android.systemui.tuner.NightModeFragment" />
+
+    <com.android.systemui.tuner.CalibratePreference
+        android:key="calibrate"
+        android:title="@string/calibrate_display" />
+
+</PreferenceScreen>
diff --git a/packages/SystemUI/res/xml/night_mode.xml b/packages/SystemUI/res/xml/night_mode.xml
new file mode 100644
index 0000000..d5f5333
--- /dev/null
+++ b/packages/SystemUI/res/xml/night_mode.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
+    android:title="@string/night_mode">
+
+    <SwitchPreference
+        android:key="auto"
+        android:title="@string/turn_on_automatically"
+        android:summary="@string/turn_on_auto_summary" />
+
+    <PreferenceCategory
+        android:title="@string/when_night_mode_on">
+
+        <SwitchPreference
+            android:key="dark_theme"
+            android:title="@string/use_dark_theme" />
+
+        <SwitchPreference
+            android:key="adjust_tint"
+            android:title="@string/adjust_tint" />
+
+        <SwitchPreference
+            android:key="adjust_brightness"
+            android:title="@string/adjust_brightness" />
+
+    </PreferenceCategory>
+
+    <Preference
+        android:selectable="false"
+        android:summary="@string/night_mode_disclaimer" />
+
+</PreferenceScreen>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 39281bc..023a3f0 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -18,19 +18,10 @@
     xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:title="@string/system_ui_tuner">
 
-    <com.android.systemui.tuner.TunerSwitch
-        android:key="qs_show_brightness"
-        android:title="@string/show_brightness"
-        sysui:defValue="true" />
-
     <PreferenceScreen
         android:key="status_bar"
         android:title="@string/status_bar" >
 
-        <Preference
-            android:selectable="false"
-            android:summary="@string/tuner_status_bar_explanation" />
-
         <com.android.systemui.tuner.StatusBarSwitch
             android:key="rotate"
             android:title="@string/status_bar_settings_auto_rotation" />
@@ -91,9 +82,10 @@
 
         <!-- other weird signal stuff -->
 
-        <com.android.systemui.tuner.StatusBarSwitch
-            android:key="battery"
-            android:title="@string/battery" />
+        <com.android.systemui.tuner.BatteryPreference
+            android:title="@string/battery"
+            android:summary="%s"
+            android:entries="@array/battery_options" />
 
         <com.android.systemui.tuner.StatusBarSwitch
             android:key="alarm_clock"
@@ -101,12 +93,37 @@
 
         <!-- secure -->
 
-        <com.android.systemui.tuner.StatusBarSwitch
-            android:key="clock"
-            android:title="@string/clock" />
+        <com.android.systemui.tuner.ClockPreference
+            android:title="@string/tuner_time"
+            android:summary="%s"
+            android:entries="@array/clock_options" />
 
     </PreferenceScreen>
 
+    <Preference
+        android:key="color_transform"
+        android:title="@string/color_and_appearance"
+        android:fragment="com.android.systemui.tuner.ColorAndAppearanceFragment" />
+
+    <PreferenceScreen
+        android:key="volume_and_do_not_disturb"
+        android:title="@string/volume_and_do_not_disturb">
+
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="sysui_show_full_zen"
+            android:title="@string/tuner_full_zen_title" />
+
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="sysui_volume_down_silent,sysui_volume_up_silent"
+            android:title="@string/volume_dnd_silent"
+            sysui:defValue="true" />
+
+    </PreferenceScreen>
+
+    <Preference
+        android:key="nav_bar"
+        android:title="@string/nav_bar"
+        android:fragment="com.android.systemui.tuner.NavBarTuner" />
 
     <PreferenceScreen
         android:key="overview"
@@ -124,53 +141,6 @@
 
     </PreferenceScreen>
 
-    <SwitchPreference
-        android:key="battery_pct"
-        android:title="@string/show_battery_percentage"
-        android:summary="@string/show_battery_percentage_summary"
-        android:persistent="false" />
-
-    <com.android.systemui.tuner.TunerSwitch
-        android:key="clock_seconds"
-        android:title="@string/clock_seconds"
-        android:summary="@string/clock_seconds_desc" />
-
-    <Preference
-        android:key="demo_mode"
-        android:title="@string/demo_mode"
-        android:fragment="com.android.systemui.tuner.DemoModeFragment" />
-
-    <Preference
-        android:key="color_transform"
-        android:title="@string/color_transform"
-        android:fragment="com.android.systemui.tuner.ColorMatrixFragment" />
-
-    <PreferenceScreen
-        android:key="volume_and_do_not_disturb"
-        android:title="@string/volume_and_do_not_disturb">
-
-        <com.android.systemui.tuner.TunerSwitch
-            android:key="sysui_show_full_zen"
-            android:title="@string/tuner_full_zen_title"
-            android:summary="@string/tuner_full_zen_summary" />
-
-        <com.android.systemui.tuner.TunerSwitch
-            android:key="sysui_volume_down_silent"
-            android:title="@string/volume_down_silent"
-            sysui:defValue="true" />
-
-        <com.android.systemui.tuner.TunerSwitch
-            android:key="sysui_volume_up_silent"
-            android:title="@string/volume_up_silent"
-            sysui:defValue="true" />
-
-    </PreferenceScreen>
-
-    <Preference
-        android:key="nav_bar"
-        android:title="@string/nav_bar"
-        android:fragment="com.android.systemui.tuner.NavBarTuner" />
-
     <!-- Warning, this goes last. -->
     <Preference
         android:summary="@string/tuner_persistent_warning"
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 33b43fe..33f3c30 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -69,9 +69,9 @@
     private float mPerpendicularInitialTouchPos;
     private boolean mDragging;
     private View mCurrView;
-    private View mCurrAnimView;
     private boolean mCanCurrViewBeDimissed;
     private float mDensityScale;
+    private float mTranslation = 0;
 
     private boolean mLongPressSent;
     private LongPressListener mLongPressListener;
@@ -121,7 +121,7 @@
         return mSwipeDirection == X ? ev.getY() : ev.getX();
     }
 
-    private float getTranslation(View v) {
+    protected float getTranslation(View v) {
         return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY();
     }
 
@@ -130,7 +130,7 @@
                 vt.getYVelocity();
     }
 
-    private ObjectAnimator createTranslationAnimation(View v, float newPos) {
+    protected ObjectAnimator createTranslationAnimation(View v, float newPos) {
         ObjectAnimator anim = ObjectAnimator.ofFloat(v,
                 mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
         return anim;
@@ -141,7 +141,17 @@
                 vt.getXVelocity();
     }
 
-    private void setTranslation(View v, float translate) {
+    protected Animator getViewTranslationAnimator(View v, float target,
+            AnimatorUpdateListener listener) {
+        ObjectAnimator anim = createTranslationAnimation(v, target);
+        anim.addUpdateListener(listener);
+        return anim;
+    }
+
+    protected void setTranslation(View v, float translate) {
+        if (v == null) {
+            return;
+        }
         if (mSwipeDirection == X) {
             v.setTranslationX(translate);
         } else {
@@ -237,15 +247,16 @@
                 mTouchAboveFalsingThreshold = false;
                 mDragging = false;
                 mLongPressSent = false;
-                mCurrView = mCallback.getChildAtPosition(ev);
                 mVelocityTracker.clear();
+                mCurrView = mCallback.getChildAtPosition(ev);
+
                 if (mCurrView != null) {
-                    mCurrAnimView = mCallback.getChildContentView(mCurrView);
+                    onDownUpdate(mCurrView);
                     mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
                     mVelocityTracker.addMovement(ev);
                     mInitialTouchPos = getPos(ev);
                     mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
-
+                    mTranslation = getTranslation(mCurrView);
                     if (mLongPressListener != null) {
                         if (mWatchLongPress == null) {
                             mWatchLongPress = new Runnable() {
@@ -268,7 +279,6 @@
                         }
                         mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
                     }
-
                 }
                 break;
 
@@ -283,8 +293,8 @@
                             && Math.abs(delta) > Math.abs(deltaPerpendicular)) {
                         mCallback.onBeginDrag(mCurrView);
                         mDragging = true;
-                        mInitialTouchPos = getPos(ev) - getTranslation(mCurrAnimView);
-
+                        mInitialTouchPos = getPos(ev);
+                        mTranslation = getTranslation(mCurrView);
                         removeLongPressCallback();
                     }
                 }
@@ -295,7 +305,6 @@
                 final boolean captured = (mDragging || mLongPressSent);
                 mDragging = false;
                 mCurrView = null;
-                mCurrAnimView = null;
                 mLongPressSent = false;
                 removeLongPressCallback();
                 if (captured) return true;
@@ -320,12 +329,11 @@
      * @param useAccelerateInterpolator Should an accelerating Interpolator be used
      * @param fixedDuration If not 0, this exact duration will be taken
      */
-    public void dismissChild(final View view, float velocity, final Runnable endAction,
+    public void dismissChild(final View animView, float velocity, final Runnable endAction,
             long delay, boolean useAccelerateInterpolator, long fixedDuration) {
-        final View animView = mCallback.getChildContentView(view);
-        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
+        final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
         float newPos;
-        boolean isLayoutRtl = view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
 
         if (velocity < 0
                 || (velocity == 0 && getTranslation(animView) < 0)
@@ -355,7 +363,13 @@
         if (!mDisableHwLayers) {
             animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         }
-        ObjectAnimator anim = createTranslationAnimation(animView, newPos);
+        AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
+            public void onAnimationUpdate(ValueAnimator animation) {
+                onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
+            }
+        };
+
+        Animator anim = getViewTranslationAnimator(animView, newPos, updateListener);
         if (useAccelerateInterpolator) {
             anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
         } else {
@@ -367,8 +381,8 @@
         }
         anim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
-                updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
-                mCallback.onChildDismissed(view);
+                updateSwipeProgressFromOffset(animView, canBeDismissed);
+                mCallback.onChildDismissed(animView);
                 if (endAction != null) {
                     endAction.run();
                 }
@@ -377,11 +391,6 @@
                 }
             }
         });
-        anim.addUpdateListener(new AnimatorUpdateListener() {
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
-            }
-        });
         prepareDismissAnimation(animView, anim);
         anim.start();
     }
@@ -393,21 +402,21 @@
         // Do nothing
     }
 
-    public void snapChild(final View view, float velocity) {
-        final View animView = mCallback.getChildContentView(view);
-        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(animView);
-        ObjectAnimator anim = createTranslationAnimation(animView, 0);
+    public void snapChild(final View animView, final float targetLeft, float velocity) {
+        final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
+        AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
+            public void onAnimationUpdate(ValueAnimator animation) {
+                onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
+            }
+        };
+
+        Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
         int duration = SNAP_ANIM_LEN;
         anim.setDuration(duration);
-        anim.addUpdateListener(new AnimatorUpdateListener() {
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
-            }
-        });
         anim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animator) {
-                updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
-                mCallback.onChildSnappedBack(animView);
+                updateSwipeProgressFromOffset(animView, canBeDismissed);
+                mCallback.onChildSnappedBack(animView, targetLeft);
             }
         });
         prepareSnapBackAnimation(animView, anim);
@@ -421,6 +430,28 @@
         // Do nothing
     }
 
+    /**
+     * Called when there's a down event.
+     */
+    public void onDownUpdate(View currView) {
+        // Do nothing
+    }
+
+    /**
+     * Called on a move event.
+     */
+    protected void onMoveUpdate(View view, float totalTranslation, float delta) {
+        // Do nothing
+    }
+
+    /**
+     * Called in {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)} when the current
+     * view is being animated to dismiss or snap.
+     */
+    public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
+        updateSwipeProgressFromOffset(animView, canBeDismissed);
+    }
+
     public boolean onTouchEvent(MotionEvent ev) {
         if (mLongPressSent) {
             return true;
@@ -456,17 +487,18 @@
                     // don't let items that can't be dismissed be dragged more than
                     // maxScrollDistance
                     if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
-                        float size = getSize(mCurrAnimView);
-                        float maxScrollDistance = 0.15f * size;
+                        float size = getSize(mCurrView);
+                        float maxScrollDistance = 0.25f * size;
                         if (absDelta >= size) {
                             delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
                         } else {
                             delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2));
                         }
                     }
-                    setTranslation(mCurrAnimView, delta);
 
-                    updateSwipeProgressFromOffset(mCurrAnimView, mCanCurrViewBeDimissed);
+                    setTranslation(mCurrView, mTranslation + delta);
+                    updateSwipeProgressFromOffset(mCurrView, mCanCurrViewBeDimissed);
+                    onMoveUpdate(mCurrView, mTranslation + delta, delta);
                 }
                 break;
             case MotionEvent.ACTION_UP:
@@ -478,12 +510,13 @@
                     float velocity = getVelocity(mVelocityTracker);
                     float perpendicularVelocity = getPerpendicularVelocity(mVelocityTracker);
 
+                    float translation = getTranslation(mCurrView);
                     // Decide whether to dismiss the current view
                     boolean childSwipedFarEnough = DISMISS_IF_SWIPED_FAR_ENOUGH &&
-                            Math.abs(getTranslation(mCurrAnimView)) > 0.4 * getSize(mCurrAnimView);
+                            Math.abs(translation) > 0.4 * getSize(mCurrView);
                     boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) &&
                             (Math.abs(velocity) > Math.abs(perpendicularVelocity)) &&
-                            (velocity > 0) == (getTranslation(mCurrAnimView) > 0);
+                            (velocity > 0) == (translation > 0);
                     boolean falsingDetected = mCallback.isAntiFalsingNeeded();
 
                     if (mFalsingManager.isClassiferEnabled()) {
@@ -502,7 +535,7 @@
                     } else {
                         // snappity
                         mCallback.onDragCancelled(mCurrView);
-                        snapChild(mCurrView, velocity);
+                        snapChild(mCurrView, 0 /* leftTarget */, velocity);
                     }
                 }
                 break;
@@ -518,8 +551,6 @@
     public interface Callback {
         View getChildAtPosition(MotionEvent ev);
 
-        View getChildContentView(View v);
-
         boolean canChildBeDismissed(View v);
 
         boolean isAntiFalsingNeeded();
@@ -530,7 +561,13 @@
 
         void onDragCancelled(View v);
 
-        void onChildSnappedBack(View animView);
+        /**
+         * Called when the child is snapped to a position.
+         *
+         * @param animView the view that was snapped.
+         * @param targetLeft the left position the view was snapped to.
+         */
+        void onChildSnappedBack(View animView, float targetLeft);
 
         /**
          * Updates the swipe progress on a child.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 8e9857d..0915ee1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -27,6 +27,7 @@
 
     private int mNumPages;
     private View mDecorGroup;
+    private PageListener mPageListener;
 
     public PagedTileLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -36,10 +37,14 @@
             public void onPageSelected(int position) {
                 if (mPageIndicator == null) return;
                 mPageIndicator.setLocation(position);
+                if (mPageListener != null) {
+                    mPageListener.onPageChanged(position);
+                }
             }
 
             @Override
-            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+            public void onPageScrolled(int position, float positionOffset,
+                    int positionOffsetPixels) {
                 if (mPageIndicator == null) return;
                 mPageIndicator.setLocation(position + positionOffset);
             }
@@ -80,6 +85,10 @@
         }
     }
 
+    public void setPageListener(PageListener listener) {
+        mPageListener = listener;
+    }
+
     private void postDistributeTiles() {
         removeCallbacks(mDistribute);
         post(mDistribute);
@@ -198,4 +207,8 @@
             return view == object;
         }
     };
+
+    public interface PageListener {
+        void onPageChanged(int page);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
new file mode 100644
index 0000000..6479b0c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -0,0 +1,208 @@
+/*
+ * 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.qs;
+
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnLayoutChangeListener;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.PathInterpolator;
+import android.widget.TextView;
+import com.android.systemui.Interpolators;
+import com.android.systemui.qs.PagedTileLayout.PageListener;
+import com.android.systemui.qs.QSPanel.QSTileLayout;
+import com.android.systemui.qs.QSTile.Host.Callback;
+import com.android.systemui.qs.TouchAnimator.Builder;
+import com.android.systemui.qs.TouchAnimator.Listener;
+import com.android.systemui.statusbar.phone.QSTileHost;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class QSAnimator implements Callback, PageListener, Listener, OnLayoutChangeListener {
+
+    private static final String TAG = "QSAnimator";
+
+    public static final PathInterpolator TRANSLATION_Y_INTERPOLATOR =
+            new PathInterpolator(.1f, .3f, 1, 1);
+
+    public static final float EXPANDED_TILE_DELAY = .7f;
+
+    private final ArrayList<View> mAllViews = new ArrayList<>();
+    private final QuickQSPanel mQuickQsPanel;
+    private final QSPanel mQsPanel;
+    private final QSContainer mQsContainer;
+
+    private boolean mOnFirstPage = true;
+    private TouchAnimator mFirstPageAnimator;
+    private TouchAnimator mFirstPageDelayedAnimator;
+    private TouchAnimator mTranslationYAnimator;
+    private TouchAnimator mNonfirstPageAnimator;
+
+    public QSAnimator(QSContainer container, QuickQSPanel quickPanel, QSPanel panel) {
+        mQsContainer = container;
+        mQuickQsPanel = quickPanel;
+        mQsPanel = panel;
+        mQuickQsPanel.addOnLayoutChangeListener(this);
+        mQsPanel.addOnLayoutChangeListener(this);
+        QSTileLayout tileLayout = mQsPanel.getTileLayout();
+        if (tileLayout instanceof PagedTileLayout) {
+            ((PagedTileLayout) tileLayout).setPageListener(this);
+        } else {
+            Log.w(TAG, "QS Not using page layout");
+        }
+    }
+
+    public void setHost(QSTileHost qsh) {
+        qsh.addCallback(this);
+    }
+
+    @Override
+    public void onPageChanged(int page) {
+        mOnFirstPage = page == 0;
+        if (!mOnFirstPage) {
+            clearAnimationState();
+        }
+    }
+
+    private void updateAnimators() {
+        TouchAnimator.Builder firstPageBuilder = new Builder();
+        TouchAnimator.Builder translationYBuilder = new Builder();
+        TouchAnimator.Builder firstPageDelayedBuilder = new Builder();
+        Collection<QSTile<?>> tiles = mQsPanel.getHost().getTiles();
+        int count = 0;
+        int[] loc1 = new int[2];
+        int[] loc2 = new int[2];
+        firstPageDelayedBuilder.setStartDelay(EXPANDED_TILE_DELAY);
+        firstPageBuilder.setListener(this);
+        translationYBuilder.setInterpolator(TRANSLATION_Y_INTERPOLATOR);
+        mAllViews.clear();
+        for (QSTile<?> tile : tiles) {
+            QSTileBaseView tileView = mQsPanel.getTileView(tile);
+            final TextView label = ((QSTileView) tileView).getLabel();
+            if (count++ < 5) {
+                // Quick tiles.
+                QSTileBaseView quickTileView = mQuickQsPanel.getTileView(tile);
+                final View tileIcon = tileView.getIcon();
+
+                getRelativePosition(loc1, quickTileView.getIcon(), mQsContainer);
+                getRelativePosition(loc2, tileIcon, mQsContainer);
+                final int xDiff = loc2[0] - loc1[0];
+                final int yDiff = loc2[1] - loc1[1];
+                // Move the quick tile right from its location to the new one.
+                firstPageBuilder.addFloat(quickTileView, "translationX", 0, xDiff);
+                translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff);
+
+                // Counteract the parent translation on the tile. So we have a static base to
+                // animate off from.
+                firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0);
+
+                // Move the real tile's icon and label from the quick tile position to its final
+                // location.
+                firstPageBuilder.addFloat(tileIcon, "translationX", -xDiff, 0);
+                translationYBuilder.addFloat(tileIcon, "translationY", -yDiff, 0);
+                firstPageBuilder.addFloat(label, "translationX", -xDiff, 0);
+                translationYBuilder.addFloat(label, "translationY", -yDiff, 0);
+
+                // Fade in the label as we reach the final position.
+                firstPageDelayedBuilder.addFloat(label, "alpha", 0, 1);
+                mAllViews.add(quickTileView);
+            } else {
+                firstPageDelayedBuilder.addFloat(tileView, "alpha", 0, 1);
+            }
+            mAllViews.add(tileView);
+            mAllViews.add(label);
+        }
+        mFirstPageAnimator = firstPageBuilder.build();
+        mFirstPageDelayedAnimator = firstPageDelayedBuilder.build();
+        mTranslationYAnimator = translationYBuilder.build();
+        mNonfirstPageAnimator = new TouchAnimator.Builder()
+                .addFloat(mQuickQsPanel, "alpha", 1, 0)
+                .setEndDelay(.5f)
+                .build();
+    }
+
+    private void getRelativePosition(int[] loc1, View view, View parent) {
+        loc1[0] = 0 + view.getWidth() / 2;
+        loc1[1] = 0;
+        getRelativePositionInt(loc1, view, parent);
+    }
+
+    private void getRelativePositionInt(int[] loc1, View view, View parent) {
+        if(view == parent || view == null) return;
+        loc1[0] += view.getLeft();
+        loc1[1] += view.getTop();
+        getRelativePositionInt(loc1, (View) view.getParent(), parent);
+    }
+
+    public void setPosition(float position) {
+        if (mFirstPageAnimator == null) return;
+        if (mOnFirstPage) {
+            mQuickQsPanel.setAlpha(1);
+            mFirstPageAnimator.setPosition(position);
+            mFirstPageDelayedAnimator.setPosition(position);
+            mTranslationYAnimator.setPosition(position);
+        } else {
+            mNonfirstPageAnimator.setPosition(position);
+        }
+    }
+
+    @Override
+    public void onAnimationAtStart() {
+
+    }
+
+    @Override
+    public void onAnimationAtEnd() {
+        mQuickQsPanel.setVisibility(View.INVISIBLE);
+    }
+
+    @Override
+    public void onAnimationStarted() {
+        mQuickQsPanel.setVisibility(View.VISIBLE);
+    }
+
+    private void clearAnimationState() {
+        final int N = mAllViews.size();
+        mQuickQsPanel.setAlpha(0);
+        for (int i = 0; i < N; i++) {
+            View v = mAllViews.get(i);
+            v.setAlpha(1);
+            v.setTranslationX(1);
+            v.setTranslationY(1);
+        }
+    }
+
+    @Override
+    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+            int oldTop, int oldRight, int oldBottom) {
+        updateAnimators();
+    }
+
+    @Override
+    public void onTilesChanged() {
+        // Give the QS panels a moment to generate their new tiles, then create all new animators
+        // hooked up to the new views.
+        mQsPanel.post(mUpdateAnimators);
+    }
+
+    private Runnable mUpdateAnimators = new Runnable() {
+        @Override
+        public void run() {
+            updateAnimators();
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index 34dfd6c..c59da8d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -27,6 +27,7 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.BaseStatusBarHeader;
+import com.android.systemui.statusbar.phone.QSTileHost;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 
 /**
@@ -49,6 +50,7 @@
     private boolean mStackScrollerOverscrolling;
 
     private long mDelay;
+    private QSAnimator mQSAnimator;
 
     public QSContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -61,6 +63,23 @@
         mQSDetail = (QSDetail) findViewById(R.id.qs_detail);
         mQSDetail.setQsPanel(mQSPanel);
         mHeader = (BaseStatusBarHeader) findViewById(R.id.header);
+        mQSAnimator = new QSAnimator(this, (QuickQSPanel) mHeader.findViewById(R.id.quick_qs_panel),
+                mQSPanel);
+    }
+
+    public void setHost(QSTileHost qsh) {
+        mQSPanel.setHost(qsh);
+        mHeader.setQSPanel(mQSPanel);
+        mQSDetail.setHost(qsh);
+        mQSAnimator.setHost(qsh);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // Since we control our own bottom, be whatever size we want.
+        // Otherwise the QSPanel ends up with 0 height when the window is only the
+        // size of the status bar.
+        super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
     }
 
     @Override
@@ -163,6 +182,7 @@
         mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
         mQSPanel.setTranslationY(translationScaleY * mQSPanel.getHeight());
         mQSDetail.setFullyExpanded(expansion == 1);
+        mQSAnimator.setPosition(expansion);
         updateBottom();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 53abe37..30a9850 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -25,7 +25,6 @@
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import com.android.internal.logging.MetricsLogger;
@@ -45,7 +44,7 @@
 import java.util.Collection;
 
 /** View that represents the quick settings tile panel. **/
-public class QSPanel extends FrameLayout implements Tunable {
+public class QSPanel extends LinearLayout implements Tunable {
 
     public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
 
@@ -66,7 +65,6 @@
     protected QSFooter mFooter;
     private boolean mGridContentVisible = true;
 
-    protected LinearLayout mQsContainer;
     protected QSTileLayout mTileLayout;
 
     private QSCustomizer mCustomizePanel;
@@ -80,20 +78,15 @@
         super(context, attrs);
         mContext = context;
 
-
-        mQsContainer = new LinearLayout(mContext);
-        mQsContainer.setOrientation(LinearLayout.VERTICAL);
-        mQsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.WRAP_CONTENT));
-        addView(mQsContainer);
+        setOrientation(VERTICAL);
 
         mBrightnessView = LayoutInflater.from(context).inflate(
                 R.layout.quick_settings_brightness_dialog, this, false);
-        mQsContainer.addView(mBrightnessView);
+        addView(mBrightnessView);
 
         mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
-                R.layout.qs_paged_tile_layout, mQsContainer, false);
-        mQsContainer.addView((View) mTileLayout);
+                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) {
@@ -107,7 +100,7 @@
         });
 
         mFooter = new QSFooter(this, context);
-        mQsContainer.addView(mFooter.getView());
+        addView(mFooter.getView());
 
         updateResources();
 
@@ -187,7 +180,7 @@
         final Resources res = mContext.getResources();
         mPanelPaddingBottom = res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom);
         mBrightnessPaddingTop = res.getDimensionPixelSize(R.dimen.qs_brightness_padding_top);
-        mQsContainer.setPadding(0, mBrightnessPaddingTop, 0, mPanelPaddingBottom);
+        setPadding(0, mBrightnessPaddingTop, 0, mPanelPaddingBottom);
         for (TileRecord r : mRecords) {
             r.tile.clearState();
         }
@@ -214,6 +207,9 @@
     public void setExpanded(boolean expanded) {
         if (mExpanded == expanded) return;
         mExpanded = expanded;
+        if (!mExpanded && mTileLayout instanceof PagedTileLayout) {
+            ((PagedTileLayout) mTileLayout).setCurrentItem(0, false);
+        }
         MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, mExpanded);
         if (!mExpanded) {
             closeDetail();
@@ -329,7 +325,8 @@
         final View.OnLongClickListener longClick = new View.OnLongClickListener() {
             @Override
             public boolean onLongClick(View v) {
-                return false;
+                r.tile.longClick();
+                return true;
             }
         };
         r.tileView.init(click, longClick);
@@ -376,7 +373,7 @@
     }
 
     public int getGridHeight() {
-        return mQsContainer.getMeasuredHeight();
+        return getMeasuredHeight();
     }
 
     protected void handleShowDetail(Record r, boolean show) {
@@ -425,7 +422,7 @@
 
     void setGridContentVisibility(boolean visible) {
         int newVis = visible ? VISIBLE : INVISIBLE;
-        mQsContainer.setVisibility(newVis);
+        setVisibility(newVis);
         if (mGridContentVisible != visible) {
             MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, newVis);
         }
@@ -468,6 +465,19 @@
         }
     }
 
+    QSTileLayout getTileLayout() {
+        return mTileLayout;
+    }
+
+    QSTileBaseView getTileView(QSTile<?> tile) {
+        for (TileRecord r : mRecords) {
+            if (r.tile == tile) {
+                return r.tileView;
+            }
+        }
+        return null;
+    }
+
     private class H extends Handler {
         private static final int SHOW_DETAIL = 1;
         private static final int SET_TILE_VISIBILITY = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index e363b76..f02424b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -36,7 +36,7 @@
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.DisplayController;
+import com.android.systemui.statusbar.policy.NightModeController;
 import com.android.systemui.statusbar.policy.FlashlightController;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -212,9 +212,11 @@
     }
 
     protected void handleLongClick() {
-        // optional
+        mHost.startActivityDismissingKeyguard(getLongClickIntent());
     }
 
+    public abstract Intent getLongClickIntent();
+
     protected void handleClearState() {
         mTmpState = newTileState();
         mState = newTileState();
@@ -279,10 +281,11 @@
         mCallbacks.clear();
     }
 
-    protected void checkIfRestrictionEnforced(State state, String userRestriction) {
+    protected void checkIfRestrictionEnforcedByAdminOnly(State state, String userRestriction) {
         EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
                 userRestriction, ActivityManager.getCurrentUser());
-        if (admin != null) {
+        if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext,
+                userRestriction, ActivityManager.getCurrentUser())) {
             state.disabledByPolicy = true;
             state.enforcedAdmin = admin;
         } else {
@@ -400,7 +403,7 @@
         UserInfoController getUserInfoController();
         BatteryController getBatteryController();
         TileServices getTileServices();
-        DisplayController getDisplayController();
+        NightModeController getNightModeController();
         void removeTile(String tileSpec);
         ManagedProfileController getManagedProfileController();
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
index 1a854c2..f35aacf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
@@ -49,6 +49,8 @@
         // Default to Quick Tile padding, and QSTileView will specify its own padding.
         int padding = context.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding);
         setPadding(padding, padding, padding, padding);
+        setClipChildren(false);
+        setClipToPadding(false);
     }
 
     private Drawable newTileBackground() {
@@ -77,6 +79,7 @@
     public void init(OnClickListener click, OnLongClickListener longClick) {
         setClickable(true);
         setOnClickListener(click);
+        setOnLongClickListener(longClick);
     }
 
     @Override
@@ -110,6 +113,10 @@
         setContentDescription(state.contentDescription);
     }
 
+    View getIcon() {
+        return mIcon;
+    }
+
     private class H extends Handler {
         private static final int STATE_CHANGED = 1;
         public H() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 0d5d115..98a1c23 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -28,6 +28,7 @@
 
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
+import libcore.util.Objects;
 
 /** View that represents a standard quick settings tile. **/
 public class QSTileView extends QSTileBaseView {
@@ -57,6 +58,10 @@
         setGravity(Gravity.CENTER);
     }
 
+    TextView getLabel() {
+        return mLabel;
+    }
+
     private void updateTopPadding() {
         Resources res = getResources();
         int padding = res.getDimensionPixelSize(R.dimen.qs_tile_padding_top);
@@ -84,14 +89,11 @@
         addView(view);
     }
 
-    public void init(OnClickListener clickPrimary, OnLongClickListener longClick) {
-        setOnClickListener(clickPrimary);
-        setOnLongClickListener(longClick);
-    }
-
     protected void handleStateChanged(QSTile.State state) {
         super.handleStateChanged(state);
-        mLabel.setText(state.label);
+        if (!Objects.equal(mLabel.getText(), state.label)) {
+            mLabel.setText(state.label);
+        }
         mLabel.setEnabled(!state.disabledByPolicy);
         mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index d0f7e6e..abe4c77 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -43,10 +43,10 @@
             for (int i = 0; i < mRecords.size(); i++) {
                 mTileLayout.removeTile(mRecords.get(i));
             }
-            mQsContainer.removeView((View) mTileLayout);
+            removeView((View) mTileLayout);
         }
         mTileLayout = new HeaderTileLayout(context);
-        mQsContainer.addView((View) mTileLayout, 1 /* Between brightness and footer */);
+        addView((View) mTileLayout, 1 /* Between brightness and footer */);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index f7e2338..55eda98 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -81,7 +81,7 @@
             record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
             previousView = record.tileView.updateAccessibilityOrder(previousView);
         }
-        setMeasuredDimension(width, (mCellHeight + mCellMargin) * rows + mCellMargin);
+        setMeasuredDimension(width, (mCellHeight + mCellMargin) * rows);
     }
 
     private static int exactly(int size) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
index 5e6b52b..b33d31d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
@@ -15,8 +15,10 @@
 package com.android.systemui.qs;
 
 import android.animation.Keyframe;
+import android.util.Log;
 import android.util.MathUtils;
 import android.util.Property;
+import android.view.View;
 import android.view.animation.Interpolator;
 
 import java.util.ArrayList;
@@ -129,11 +131,36 @@
 
         private void add(Object target, String property, KeyframeSet keyframeSet) {
             mTargets.add(target);
-            // TODO: Optimize the properties here, to use those in View when possible.
-            mProperties.add(Property.of(target.getClass(), float.class, property));
+            mProperties.add(getProperty(target, property));
             mValues.add(keyframeSet);
         }
 
+        private static Property getProperty(Object target, String property) {
+            if (target instanceof View) {
+                switch (property) {
+                    case "translationX":
+                        return View.TRANSLATION_X;
+                    case "translationY":
+                        return View.TRANSLATION_Y;
+                    case "translationZ":
+                        return View.TRANSLATION_Z;
+                    case "alpha":
+                        return View.ALPHA;
+                    case "rotation":
+                        return View.ROTATION;
+                    case "x":
+                        return View.X;
+                    case "y":
+                        return View.Y;
+                    case "scaleX":
+                        return View.SCALE_X;
+                    case "scaleY":
+                        return View.SCALE_Y;
+                }
+            }
+            return Property.of(target.getClass(), float.class, property);
+        }
+
         public Builder setStartDelay(float startDelay) {
             mStartDelay = startDelay;
             return this;
@@ -164,77 +191,61 @@
 
     private static abstract class KeyframeSet {
 
-        private final Keyframe[] mKeyframes;
+        private final float mFrameWidth;
+        private final int mSize;
 
-        public KeyframeSet(Keyframe[] keyframes) {
-            mKeyframes = keyframes;
+        public KeyframeSet(int size) {
+            mSize = size;
+            mFrameWidth = 1 / (float) (size - 1);
         }
 
         Object getValue(float fraction) {
             int i;
-            for (i = 1; i < mKeyframes.length && fraction > mKeyframes[i].getFraction(); i++) ;
-            Keyframe first = mKeyframes[i - 1];
-            Keyframe second = mKeyframes[i];
-            float amount = (fraction - first.getFraction())
-                    / (second.getFraction() - first.getFraction());
-            return interpolate(first, second, amount);
+            for (i = 1; i < mSize - 1 && fraction > mFrameWidth; i++);
+            float amount = fraction / mFrameWidth;
+            return interpolate(i, amount);
         }
 
-        protected abstract Object interpolate(Keyframe first, Keyframe second, float amount);
+        protected abstract Object interpolate(int index, float amount);
 
         public static KeyframeSet ofInt(int... values) {
-            int numKeyframes = values.length;
-            Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes, 2)];
-            if (numKeyframes == 1) {
-                keyframes[0] = Keyframe.ofInt(0f);
-                keyframes[1] = Keyframe.ofInt(1f, values[0]);
-            } else {
-                keyframes[0] = Keyframe.ofInt(0f, values[0]);
-                for (int i = 1; i < numKeyframes; ++i) {
-                    keyframes[i] = Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]);
-                }
-            }
-            return new IntKeyframeSet(keyframes);
+            return new IntKeyframeSet(values);
         }
 
         public static KeyframeSet ofFloat(float... values) {
-            int numKeyframes = values.length;
-            Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes, 2)];
-            if (numKeyframes == 1) {
-                keyframes[0] = Keyframe.ofFloat(0f);
-                keyframes[1] = Keyframe.ofFloat(1f, values[0]);
-            } else {
-                keyframes[0] = Keyframe.ofFloat(0f, values[0]);
-                for (int i = 1; i < numKeyframes; ++i) {
-                    keyframes[i] = Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
-                }
-            }
-            return new FloatKeyframeSet(keyframes);
+            return new FloatKeyframeSet(values);
         }
     }
 
-    public static class FloatKeyframeSet extends KeyframeSet {
-        public FloatKeyframeSet(Keyframe[] keyframes) {
-            super(keyframes);
+    private static class FloatKeyframeSet extends KeyframeSet {
+        private final float[] mValues;
+
+        public FloatKeyframeSet(float[] values) {
+            super(values.length);
+            mValues = values;
         }
 
         @Override
-        protected Object interpolate(Keyframe first, Keyframe second, float amount) {
-            float firstFloat = (float) first.getValue();
-            float secondFloat = (float) second.getValue();
+        protected Object interpolate(int index, float amount) {
+            float firstFloat = mValues[index - 1];
+            float secondFloat = mValues[index];
             return firstFloat + (secondFloat - firstFloat) * amount;
         }
     }
 
-    public static class IntKeyframeSet extends KeyframeSet {
-        public IntKeyframeSet(Keyframe[] keyframes) {
-            super(keyframes);
+    private static class IntKeyframeSet extends KeyframeSet {
+
+        private final int[] mValues;
+
+        public IntKeyframeSet(int[] values) {
+            super(values.length);
+            mValues = values;
         }
 
         @Override
-        protected Object interpolate(Keyframe first, Keyframe second, float amount) {
-            int firstFloat = (int) first.getValue();
-            int secondFloat = (int) second.getValue();
+        protected Object interpolate(int index, float amount) {
+            int firstFloat = mValues[index - 1];
+            int secondFloat = mValues[index];
             return (int) (firstFloat + (secondFloat - firstFloat) * amount);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 5c34ceb..45f2d75 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -53,9 +53,9 @@
     }
 
     private void addSystemTiles(QSTileHost host) {
-        boolean hasColorMod = host.getDisplayController().isEnabled();
+        boolean hasColorMod = host.getNightModeController().isEnabled();
         String possible = mContext.getString(R.string.quick_settings_tiles_default)
-                + ",hotspot,inversion,saver,work,cast" + (hasColorMod ? ",colors" : "");
+                + ",hotspot,inversion,saver,work,cast" + (hasColorMod ? ",night" : "");
         String[] possibleTiles = possible.split(",");
         final Handler qsHandler = new Handler(host.getLooper());
         final Handler mainHandler = new Handler(Looper.getMainLooper());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 3cd9e67..0709992 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -15,13 +15,18 @@
  */
 package com.android.systemui.qs.external;
 
+import android.app.ActivityManager;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.service.quicksettings.IQSTileService;
 import android.service.quicksettings.Tile;
 import android.service.quicksettings.TileService;
@@ -156,8 +161,22 @@
     }
 
     @Override
-    protected void handleUserSwitch(int newUserId) {
-        super.handleUserSwitch(newUserId);
+    public Intent getLongClickIntent() {
+        Intent i = new Intent(TileService.ACTION_QS_TILE_PREFERENCES);
+        i.setPackage(mComponent.getPackageName());
+        i = resolveIntent(i);
+        if (i != null) {
+            return i;
+        }
+        return new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
+                Uri.fromParts("package", mComponent.getPackageName(), null));
+    }
+
+    private Intent resolveIntent(Intent i) {
+        ResolveInfo result = mContext.getPackageManager().resolveActivityAsUser(i, 0,
+                ActivityManager.getCurrentUser());
+        return result != null ? new Intent(TileService.ACTION_QS_TILE_PREFERENCES)
+                .setClassName(result.activityInfo.packageName, result.activityInfo.name) : null;
     }
 
     @Override
@@ -184,10 +203,6 @@
     }
 
     @Override
-    protected void handleLongClick() {
-    }
-
-    @Override
     protected void handleUpdateState(State state, Object arg) {
         Drawable drawable = mTile.getIcon().loadDrawable(mContext);
         int color = mContext.getColor(getColor(mTile.getState()));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 5222e61..f0860fe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
+import android.provider.Settings;
 import android.provider.Settings.Global;
 
 import com.android.internal.logging.MetricsLogger;
@@ -68,6 +69,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();
         final boolean airplaneMode = value != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 6a9d826..93e075d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -19,6 +19,7 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.provider.Settings;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.RelativeSizeSpan;
@@ -91,6 +92,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+    }
+
+    @Override
     protected void handleClick() {
         showDetail(true);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index c4b7944..80f667c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -78,6 +78,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
+    }
+
+    @Override
     protected void handleClick() {
         if (!mController.canConfigBluetooth()) {
             mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 15e082a..e0ad002 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -86,6 +86,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_CAST_SETTINGS);
+    }
+
+    @Override
     protected void handleClick() {
         if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
             mHost.startRunnableDismissingKeyguard(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 15617c7f..5f87741 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -37,7 +37,7 @@
 
 /** Quick settings tile: Cellular **/
 public class CellularTile extends QSTile<QSTile.SignalState> {
-    private static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
+    static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
             "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
 
     private final NetworkController mController;
@@ -78,6 +78,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return CELLULAR_SETTINGS;
+    }
+
+    @Override
     protected void handleClick() {
         MetricsLogger.action(mContext, getMetricsCategory());
         if (mDataController.isMobileDataSupported()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index e98734c..42ce69c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.content.Intent;
+import android.provider.Settings;
 import android.provider.Settings.Secure;
 
 import com.android.internal.logging.MetricsLogger;
@@ -70,6 +72,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
+    }
+
+    @Override
     protected void handleClick() {
         MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
         mSetting.setValue(mState.value ? 0 : 1);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index c6a98b4..a1789a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -14,6 +14,7 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.content.Intent;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
@@ -44,6 +45,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return CellularTile.CELLULAR_SETTINGS;
+    }
+
+    @Override
     protected void handleClick() {
         mState.value = !mDataSaverController.isDataSaverEnabled();
         mDataSaverController.setDataSaverEnabled(mState.value);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 29ca06b..8982b3e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -29,11 +29,13 @@
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewGroup;
+import android.widget.Toast;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
+import com.android.systemui.SysUIToast;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.volume.ZenModePanel;
@@ -99,7 +101,20 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return ZEN_SETTINGS;
+    }
+
+    @Override
     public void handleClick() {
+        if (mController.isVolumeRestricted()) {
+            // Collapse the panels, so the user can see the toast.
+            mHost.collapsePanels();
+            SysUIToast.makeText(mContext, mContext.getString(
+                    com.android.internal.R.string.error_message_change_not_allowed),
+                    Toast.LENGTH_LONG).show();
+            return;
+        }
         MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
         if (mState.value) {
             mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
@@ -116,8 +131,7 @@
         final boolean newValue = zen != Global.ZEN_MODE_OFF;
         final boolean valueChanged = state.value != newValue;
         state.value = newValue;
-        state.disabledByPolicy = mController.isVolumeRestricted();
-        checkIfRestrictionEnforced(state, UserManager.DISALLOW_ADJUST_VOLUME);
+        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
                 state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index f06634e..c10843a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -18,6 +18,8 @@
 
 import android.app.ActivityManager;
 
+import android.content.Intent;
+import android.provider.MediaStore;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -60,6 +62,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+    }
+
+    @Override
     protected void handleClick() {
         if (ActivityManager.isUserAMonkey()) {
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 943b502..ad1c7a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,8 +16,10 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.content.Intent;
 import android.os.UserManager;
 
+import android.provider.Settings;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -58,6 +60,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
+    }
+
+    @Override
     protected void handleClick() {
         final boolean isEnabled = (Boolean) mState.value;
         MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled);
@@ -68,8 +75,7 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
-        state.disabledByPolicy = mController.isTetheringAllowed();
-        checkIfRestrictionEnforced(state, UserManager.DISALLOW_CONFIG_TETHERING);
+        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_TETHERING);
         if (arg instanceof Boolean) {
             state.value = (boolean) arg;
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index bdf95d8..bb5ff8e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -92,6 +92,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return null;
+    }
+
+    @Override
     protected void handleLongClick() {
         sendIntent("long-click", mOnLongClick, mOnLongClickUri);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 9f41f9a..6533252 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -16,8 +16,10 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.content.Intent;
 import android.os.UserManager;
 
+import android.provider.Settings;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -61,6 +63,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+    }
+
+    @Override
     protected void handleClick() {
         if (mKeyguard.isSecure() && mKeyguard.isShowing()) {
             mHost.startRunnableDismissingKeyguard(new Runnable() {
@@ -87,8 +94,7 @@
         // bug is fixed, this should be reverted to only hiding it on secure lock screens:
         // state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
         state.value = locationEnabled;
-        state.disabledByPolicy = mController.isUserLocationRestricted();
-        checkIfRestrictionEnforced(state, UserManager.DISALLOW_SHARE_LOCATION);
+        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
         if (locationEnabled) {
             state.icon = mEnable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index c94cf5a..b267ccd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -17,8 +17,10 @@
 package com.android.systemui.qs.tiles;
 
 import android.content.Context;
+import android.content.Intent;
 import android.content.res.Configuration;
 
+import android.provider.Settings;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -60,6 +62,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_DISPLAY_SETTINGS);
+    }
+
+    @Override
     protected void handleClick() {
         if (mController == null) return;
         MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index ba7ea4d..f1066c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -16,7 +16,9 @@
 package com.android.systemui.qs.tiles;
 
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.drawable.Drawable;
+import android.provider.Settings;
 import android.util.Pair;
 
 import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -42,6 +44,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_USER_SETTINGS);
+    }
+
+    @Override
     protected void handleClick() {
         showDetail(true);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 7a58f15..7ee795f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -93,6 +93,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return WIFI_SETTINGS;
+    }
+
+    @Override
     protected void handleSecondaryClick() {
         // Secondary clicks are header clicks, just toggle.
         mState.copyTo(mStateBeforeClick);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 053a98a..003e9c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.content.Intent;
+import android.provider.Settings;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -52,6 +54,11 @@
     }
 
     @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_SYNC_SETTINGS);
+    }
+
+    @Override
     public void handleClick() {
         MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
         mProfileController.setWorkModeEnabled(!mState.value);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index fe504fe..3f0630d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -494,7 +494,7 @@
      * onChildDismissed() calls.
      */
     @Override
-    public void onChildSnappedBack(View v) {
+    public void onChildSnappedBack(View v, float targetLeft) {
         TaskView tv = (TaskView) v;
 
         // Re-enable clipping with the stack
@@ -517,11 +517,6 @@
     }
 
     @Override
-    public View getChildContentView(View v) {
-        return v;
-    }
-
-    @Override
     public boolean isAntiFalsingNeeded() {
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 189e651..dd59fac 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -40,6 +40,7 @@
     private DividerView mView;
     private DockDividerVisibilityListener mDockDividerVisibilityListener;
     private boolean mVisible = false;
+    private boolean mMinimized = false;
 
     @Override
     public void start() {
@@ -81,6 +82,10 @@
     private void update(Configuration configuration) {
         removeDivider();
         addDivider(configuration);
+        if (mMinimized) {
+            mView.setMinimizedDockStack(true);
+            mWindowManager.setTouchable(false);
+        }
     }
 
     private void updateVisibility(final boolean visible) {
@@ -95,6 +100,23 @@
         });
     }
 
+    private void updateMinimizedDockedStack(final boolean minimized, final long animDuration) {
+        mView.post(new Runnable() {
+            @Override
+            public void run() {
+                if (mMinimized != minimized) {
+                    mMinimized = minimized;
+                    mWindowManager.setTouchable(!minimized);
+                    if (animDuration > 0) {
+                        mView.setMinimizedDockStack(minimized, animDuration);
+                    } else {
+                        mView.setMinimizedDockStack(minimized);
+                    }
+                }
+            }
+        });
+    }
+
     class DockDividerVisibilityListener extends IDockedStackListener.Stub {
 
         @Override
@@ -105,5 +127,11 @@
         @Override
         public void onDockedStackExistsChanged(boolean exists) throws RemoteException {
         }
+
+        @Override
+        public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
+                throws RemoteException {
+            updateMinimizedDockedStack(minimized, animDuration);
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
index 36cfac8..9118e9c 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
@@ -140,4 +140,9 @@
         canvas.drawRoundRect(left, top, left + mCurrentWidth, top + mCurrentHeight,
                 radius, radius, mPaint);
     }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 1bdf5a1..65a2f8f 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -40,7 +40,6 @@
 import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
 import android.view.WindowInsets;
 import android.view.WindowManager;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
@@ -86,6 +85,11 @@
      */
     private static final float BOTTOM_RIGHT_SWITCH_BIGGER_FRACTION = 0.2f;
 
+    /**
+     * How much the background gets scaled when we are in the minimized dock state.
+     */
+    private static final float MINIMIZE_DOCK_SCALE = 0.375f;
+
     private static final PathInterpolator SLOWDOWN_INTERPOLATOR =
             new PathInterpolator(0.5f, 1f, 0.5f, 1f);
     private static final PathInterpolator DIM_INTERPOLATOR =
@@ -126,6 +130,7 @@
     private boolean mAnimateAfterRecentsDrawn;
     private boolean mGrowAfterRecentsDrawn;
     private boolean mGrowRecents;
+    private Animator mCurrentAnimator;
 
     public DividerView(Context context) {
         super(context);
@@ -205,6 +210,7 @@
     }
 
     public boolean startDragging(boolean animate, boolean touching) {
+        cancelFlingAnimation();
         if (touching) {
             mHandle.setTouching(true, animate);
         }
@@ -364,11 +370,19 @@
                 commitSnapFlags(snapTarget);
                 mWindowManagerProxy.setResizing(false);
                 mDockSide = WindowManager.DOCKED_INVALID;
+                mCurrentAnimator = null;
             }
         });
+        mCurrentAnimator = anim;
         return anim;
     }
 
+    private void cancelFlingAnimation() {
+        if (mCurrentAnimator != null) {
+            mCurrentAnimator.cancel();
+        }
+    }
+
     private void commitSnapFlags(SnapTarget target) {
         if (target.flag == SnapTarget.FLAG_NONE) {
             return;
@@ -433,6 +447,47 @@
         mBackgroundLifted = false;
     }
 
+
+    public void setMinimizedDockStack(boolean minimized) {
+        updateDockSide();
+        mHandle.setAlpha(minimized ? 0f : 1f);
+        if (mDockSide == WindowManager.DOCKED_TOP) {
+            mBackground.setPivotY(0);
+            mBackground.setScaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+        } else if (mDockSide == WindowManager.DOCKED_LEFT
+                || mDockSide == WindowManager.DOCKED_RIGHT) {
+            mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
+                    ? 0
+                    : mBackground.getWidth());
+            mBackground.setScaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+        }
+    }
+
+    public void setMinimizedDockStack(boolean minimized, long animDuration) {
+        updateDockSide();
+        mHandle.animate()
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .setDuration(animDuration)
+                .alpha(minimized ? 0f : 1f)
+                .start();
+        if (mDockSide == WindowManager.DOCKED_TOP) {
+            mBackground.setPivotY(0);
+            mBackground.animate()
+                    .scaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+        } else if (mDockSide == WindowManager.DOCKED_LEFT
+                || mDockSide == WindowManager.DOCKED_RIGHT) {
+            mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
+                    ? 0
+                    : mBackground.getWidth());
+            mBackground.animate()
+                    .scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+        }
+        mBackground.animate()
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .setDuration(animDuration)
+                .start();
+    }
+
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
index 2294d40..3db03d0 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
@@ -22,6 +22,7 @@
 import android.view.WindowManager;
 
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
 import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
@@ -79,4 +80,18 @@
             mWindowManager.updateViewLayout(mView, mLp);
         }
     }
+
+    public void setTouchable(boolean touchable) {
+        boolean changed = false;
+        if (!touchable && (mLp.flags & FLAG_NOT_TOUCHABLE) == 0) {
+            mLp.flags |= FLAG_NOT_TOUCHABLE;
+            changed = true;
+        } else if (touchable && (mLp.flags & FLAG_NOT_TOUCHABLE) != 0) {
+            mLp.flags &= ~FLAG_NOT_TOUCHABLE;
+            changed = true;
+        }
+        if (changed) {
+            mWindowManager.updateViewLayout(mView, mLp);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 874defa..315c509 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -208,6 +208,10 @@
         return false;
     }
 
+    protected boolean handleSlideBack() {
+        return false;
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         boolean result;
@@ -260,6 +264,9 @@
                 break;
             case MotionEvent.ACTION_UP:
                 if (isWithinTouchSlop(event)) {
+                    if (handleSlideBack()) {
+                        return true;
+                    }
                     if (!mActivated) {
                         makeActive();
                         postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 2bebac2..ea8b75e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -103,6 +103,7 @@
 import com.android.systemui.statusbar.policy.PreviewInflater;
 import com.android.systemui.statusbar.policy.RemoteInputView;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.GearDisplayedListener;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 
 import java.util.ArrayList;
@@ -115,7 +116,7 @@
 public abstract class BaseStatusBar extends SystemUI implements
         CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener,
         ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
-        ExpandableNotificationRow.OnExpandClickListener {
+        ExpandableNotificationRow.OnExpandClickListener, GearDisplayedListener {
     public static final String TAG = "StatusBar";
     public static final boolean DEBUG = false;
     public static final boolean MULTIUSER_DEBUG = false;
@@ -220,6 +221,7 @@
 
     // which notification is currently being longpress-examined by the user
     private NotificationGuts mNotificationGutsExposed;
+    private ExpandableNotificationRow mNotificationGearDisplayed;
 
     private KeyboardShortcuts mKeyboardShortcuts;
 
@@ -1008,6 +1010,10 @@
         guts.bindImportance(sbn, row, mNotificationData.getImportance(sbn.getKey()));
     }
 
+    protected GearDisplayedListener getGearDisplayedListener() {
+        return this;
+    }
+
     protected SwipeHelper.LongPressListener getNotificationLongClicker() {
         return new SwipeHelper.LongPressListener() {
             @Override
@@ -1020,7 +1026,7 @@
                     return false;
                 }
 
-                ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+                final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
                 bindGuts(row);
 
                 // Assume we are a status_bar_notification_row
@@ -1052,6 +1058,14 @@
                                 = ViewAnimationUtils.createCircularReveal(guts, x, y, 0, r);
                         a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
                         a.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+                        a.addListener(new AnimatorListenerAdapter() {
+                            @Override
+                            public void onAnimationEnd(Animator animation) {
+                                super.onAnimationEnd(animation);
+                                // Move the notification view back over the gear
+                                row.resetTranslation();
+                            }
+                        });
                         a.start();
                         guts.setExposed(true);
                         mStackScroller.onHeightChanged(null, true /* needsAnimation */);
@@ -1063,6 +1077,11 @@
         };
     }
 
+    @Override
+    public void onGearDisplayed(ExpandableNotificationRow row) {
+        mNotificationGearDisplayed = row;
+    }
+
     public void dismissPopups() {
         dismissPopups(-1, -1);
     }
@@ -1095,6 +1114,11 @@
             v.setExposed(false);
             mStackScroller.onHeightChanged(null, true /* needsAnimation */);
         }
+
+        if (mNotificationGearDisplayed != null) {
+            mNotificationGearDisplayed.resetTranslation();
+            mNotificationGearDisplayed = null;
+        }
     }
 
     @Override
@@ -1633,6 +1657,12 @@
                 return;
             }
 
+            // Check if the notification is displaying the gear, if so slide notification back
+            if (row.getSettingsRow() != null && row.getSettingsRow().isVisible()) {
+                row.animateTranslateNotification(0);
+                return;
+            }
+
             Notification notification = sbn.getNotification();
             final PendingIntent intent = notification.contentIntent != null
                     ? notification.contentIntent
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 7422902..c73e115 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -16,6 +16,12 @@
 
 package com.android.systemui.statusbar;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.Notification;
 import android.content.Context;
 import android.graphics.drawable.AnimatedVectorDrawable;
@@ -45,6 +51,7 @@
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 import com.android.systemui.statusbar.stack.StackViewState;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class ExpandableNotificationRow extends ActivatableNotificationView {
@@ -87,6 +94,8 @@
      */
     private boolean mOnKeyguard;
 
+    private AnimatorSet mTranslateAnim;
+    private ArrayList<View> mTranslateableViews;
     private NotificationContentView mPublicLayout;
     private NotificationContentView mPrivateLayout;
     private int mMaxExpandHeight;
@@ -96,6 +105,7 @@
     private ExpansionLogger mLogger;
     private String mLoggingKey;
     private boolean mWasReset;
+    private NotificationSettingsIconRow mSettingsIconRow;
     private NotificationGuts mGuts;
     private NotificationData.Entry mEntry;
     private StatusBarNotification mStatusBarNotification;
@@ -108,6 +118,7 @@
     private boolean mChildrenExpanded;
     private boolean mIsSummaryWithChildren;
     private NotificationChildrenContainer mChildrenContainer;
+    private ViewStub mSettingsIconRowStub;
     private ViewStub mGutsStub;
     private boolean mIsSystemChildExpanded;
     private boolean mIsPinned;
@@ -240,7 +251,6 @@
                 != com.android.internal.R.id.status_bar_latest_event_content;
         int headsUpheight = headsUpCustom && beforeN ? mMaxHeadsUpHeightLegacy
                 : mMaxHeadsUpHeight;
-        mMaxViewHeight = mNotificationMaxHeight;
         mPrivateLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
         mPublicLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
     }
@@ -329,6 +339,15 @@
     }
 
     @Override
+    protected boolean handleSlideBack() {
+        if (mSettingsIconRow != null && mSettingsIconRow.isVisible()) {
+            animateTranslateNotification(0 /* targetLeft */);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
     protected boolean shouldHideBackground() {
         return super.shouldHideBackground() || mShowNoBackground;
     }
@@ -500,6 +519,13 @@
         return mPrivateLayout.getNotificationHeader();
     }
 
+    private NotificationHeaderView getVisibleNotificationHeader() {
+        if (mNotificationHeader != null) {
+            return mNotificationHeader;
+        }
+        return getShowingLayout().getVisibleNotificationHeader();
+    }
+
     public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
         mOnExpandClickListener = onExpandClickListener;
     }
@@ -527,6 +553,17 @@
             mGuts.setVisibility(oldGuts.getVisibility());
             addView(mGuts, index);
         }
+        if (mSettingsIconRow != null) {
+            View oldSettings = mSettingsIconRow;
+            int settingsIndex = indexOfChild(oldSettings);
+            removeView(oldSettings);
+            mSettingsIconRow = (NotificationSettingsIconRow) LayoutInflater.from(mContext).inflate(
+                    R.layout.notification_settings_icon_row, this, false);
+            mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
+            mSettingsIconRow.setVisibility(oldSettings.getVisibility());
+            addView(mSettingsIconRow, settingsIndex);
+
+        }
         mPrivateLayout.reInflateViews();
         mPublicLayout.reInflateViews();
     }
@@ -542,16 +579,23 @@
     }
 
     private void initDimens() {
-        mNotificationMinHeightLegacy =  getResources().getDimensionPixelSize(
-                R.dimen.notification_min_height_legacy);
-        mNotificationMinHeight =  getResources().getDimensionPixelSize(
-                R.dimen.notification_min_height);
-        mNotificationMaxHeight =  getResources().getDimensionPixelSize(
-                R.dimen.notification_max_height);
-        mMaxHeadsUpHeightLegacy =  getResources().getDimensionPixelSize(
+        mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
+        mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
+        mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
+        mMaxHeadsUpHeightLegacy = getFontScaledHeight(
                 R.dimen.notification_max_heads_up_height_legacy);
-        mMaxHeadsUpHeight =  getResources().getDimensionPixelSize(
-                R.dimen.notification_max_heads_up_height);
+        mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
+    }
+
+    /**
+     * @param dimenId the dimen to look up
+     * @return the font scaled dimen as if it were in sp but doesn't shrink sizes below dp
+     */
+    private int getFontScaledHeight(int dimenId) {
+        int dimensionPixelSize = getResources().getDimensionPixelSize(dimenId);
+        float factor = Math.max(1.0f, getResources().getDisplayMetrics().scaledDensity /
+                getResources().getDisplayMetrics().density);
+        return (int) (dimensionPixelSize * factor);
     }
 
     /**
@@ -561,7 +605,6 @@
     public void reset() {
         super.reset();
         final boolean wasExpanded = isExpanded();
-        mMaxViewHeight = 0;
         mExpandable = false;
         mHasUserChangedExpansion = false;
         mUserLocked = false;
@@ -573,6 +616,7 @@
         mPublicLayout.reset(mIsHeadsUp);
         mPrivateLayout.reset(mIsHeadsUp);
         resetHeight();
+        resetTranslation();
         logExpansionEvent(false, wasExpanded);
     }
 
@@ -596,6 +640,14 @@
         mPrivateLayout.setExpandClickListener(mExpandClickListener);
         mPrivateLayout.setContainingNotification(this);
         mPublicLayout.setExpandClickListener(mExpandClickListener);
+        mSettingsIconRowStub = (ViewStub) findViewById(R.id.settings_icon_row_stub);
+        mSettingsIconRowStub.setOnInflateListener(new ViewStub.OnInflateListener() {
+            @Override
+            public void onInflate(ViewStub stub, View inflated) {
+                mSettingsIconRow = (NotificationSettingsIconRow) inflated;
+                mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
+            }
+        });
         mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
         mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
             @Override
@@ -603,6 +655,7 @@
                 mGuts = (NotificationGuts) inflated;
                 mGuts.setClipTopAmount(getClipTopAmount());
                 mGuts.setActualHeight(getActualHeight());
+                mTranslateableViews.add(mGuts);
                 mGutsStub = null;
             }
         });
@@ -613,9 +666,89 @@
             public void onInflate(ViewStub stub, View inflated) {
                 mChildrenContainer = (NotificationChildrenContainer) inflated;
                 mChildrenContainer.setNotificationParent(ExpandableNotificationRow.this);
+                mTranslateableViews.add(mChildrenContainer);
             }
         });
         mVetoButton = findViewById(R.id.veto);
+
+        // Add the views that we translate to reveal the gear
+        mTranslateableViews = new ArrayList<View>();
+        for (int i = 0; i < getChildCount(); i++) {
+            mTranslateableViews.add(getChildAt(i));
+        }
+        // Remove views that don't translate
+        mTranslateableViews.remove(mVetoButton);
+        mTranslateableViews.remove(mSettingsIconRowStub);
+        mTranslateableViews.remove(mChildrenContainerStub);
+        mTranslateableViews.remove(mGutsStub);
+    }
+
+    public void setTranslationForOutline(float translationX) {
+        setOutlineRect(false, translationX, getTop(), getRight() + translationX, getBottom());
+    }
+
+    public void resetTranslation() {
+        if (mTranslateableViews != null) {
+            for (int i = 0; i < mTranslateableViews.size(); i++) {
+                mTranslateableViews.get(i).setTranslationX(0);
+            }
+            setTranslationForOutline(0);
+        }
+        if (mSettingsIconRow != null) {
+            mSettingsIconRow.resetState();
+        }
+    }
+
+    public void animateTranslateNotification(final float leftTarget) {
+        if (mTranslateAnim != null) {
+            mTranslateAnim.cancel();
+        }
+        AnimatorSet set = new AnimatorSet();
+        if (mTranslateableViews != null) {
+            for (int i = 0; i < mTranslateableViews.size(); i++) {
+                final View animView = mTranslateableViews.get(i);
+                final ObjectAnimator translateAnim = ObjectAnimator.ofFloat(
+                        animView, "translationX", leftTarget);
+                if (i == 0) {
+                    translateAnim.addUpdateListener(new AnimatorUpdateListener() {
+                        @Override
+                        public void onAnimationUpdate(ValueAnimator animation) {
+                            setTranslationForOutline((float) animation.getAnimatedValue());
+                        }
+                    });
+                }
+                translateAnim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator anim) {
+                        if (mSettingsIconRow != null && leftTarget == 0) {
+                            mSettingsIconRow.resetState();
+                        }
+                        mTranslateAnim = null;
+                    }
+                });
+                set.play(translateAnim);
+            }
+        }
+        mTranslateAnim = set;
+        set.start();
+    }
+
+    public float getSpaceForGear() {
+        if (mSettingsIconRow != null) {
+            return mSettingsIconRow.getSpaceForGear();
+        }
+        return 0;
+    }
+
+    public NotificationSettingsIconRow getSettingsRow() {
+        if (mSettingsIconRow == null) {
+            mSettingsIconRowStub.inflate();
+        }
+        return mSettingsIconRow;
+    }
+
+    public ArrayList<View> getContentViews() {
+        return mTranslateableViews;
     }
 
     public void inflateGuts() {
@@ -772,7 +905,7 @@
                 if (mIsSummaryWithChildren) {
                     mChildrenContainer.updateGroupOverflow();
                 }
-                notifyHeightChanged(false  /* needsAnimation */);
+                notifyHeightChanged(false /* needsAnimation */);
             }
         }
     }
@@ -1097,6 +1230,7 @@
             mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(),
                     mNotificationHeader);
             addView(mNotificationHeader, indexOfChild(mChildrenContainer) + 1);
+            mTranslateableViews.add(mNotificationHeader);
         } else {
             header.reapply(getContext(), mNotificationHeader);
             mNotificationHeaderWrapper.notifyContentUpdated(mEntry.notification);
@@ -1166,7 +1300,7 @@
     protected boolean disallowSingleClick(MotionEvent event) {
         float x = event.getX();
         float y = event.getY();
-        NotificationHeaderView header = getNotificationHeader();
+        NotificationHeaderView header = getVisibleNotificationHeader();
         if (header != null) {
             return header.isInTouchRect(x, y);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 44c6a5d..782a38c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -81,8 +81,13 @@
     }
 
     protected void setOutlineRect(float left, float top, float right, float bottom) {
+        setOutlineRect(true, left, top, right, bottom);
+    }
+
+    protected void setOutlineRect(boolean clipToOutline, float left, float top, float right,
+            float bottom) {
         mCustomOutline = true;
-        setClipToOutline(true);
+        setClipToOutline(clipToOutline);
 
         mOutlineRect.set((int) left, (int) top, (int) right, (int) bottom);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 8042b60..3176e2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -24,7 +24,6 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import com.android.systemui.R;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import java.util.ArrayList;
@@ -35,7 +34,6 @@
 public abstract class ExpandableView extends FrameLayout {
 
     protected OnHeightChangedListener mOnHeightChangedListener;
-    protected int mMaxViewHeight;
     private int mActualHeight;
     protected int mClipTopAmount;
     private boolean mActualHeightInitialized;
@@ -49,8 +47,6 @@
 
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mMaxViewHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_max_height);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index d5361dd..647f0bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -144,11 +144,11 @@
         }
         if (mContractedChild != null) {
             int heightSpec;
+            int size = Math.min(maxSize, mSmallHeight);
             if (shouldContractedBeFixedSize()) {
-                int size = Math.min(maxSize, mSmallHeight);
                 heightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
             } else {
-                heightSpec = MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.AT_MOST);
+                heightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
             }
             mContractedChild.measure(widthMeasureSpec, heightSpec);
             int measuredHeight = mContractedChild.getMeasuredHeight();
@@ -475,6 +475,19 @@
         }
     }
 
+    private NotificationViewWrapper getCurrentVisibleWrapper() {
+        switch (mVisibleType) {
+            case VISIBLE_TYPE_EXPANDED:
+                return mExpandedWrapper;
+            case VISIBLE_TYPE_HEADSUP:
+                return mHeadsUpWrapper;
+            case VISIBLE_TYPE_CONTRACTED:
+                return mContractedWrapper;
+            default:
+                return null;
+        }
+    }
+
     /**
      * @return one of the static enum types in this view, calculated form the current state
      */
@@ -684,6 +697,11 @@
         return header;
     }
 
+    public NotificationHeaderView getVisibleNotificationHeader() {
+        NotificationViewWrapper wrapper = getCurrentVisibleWrapper();
+        return wrapper == null ? null : wrapper.getNotificationHeader();
+    }
+
     public void setContainingNotification(ExpandableNotificationRow containingNotification) {
         mContainingNotification = containingNotification;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 2cacb8a..ccd0ad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -34,6 +34,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Objects;
 
 /**
  * The list of currently displaying notifications.
@@ -118,10 +119,16 @@
                 final RemoteViews newPublicNotification
                         = updatedNotificationBuilder.makePublicContentView();
 
+                boolean sameCustomView = Objects.equals(
+                        notification.getNotification().extras.getBoolean(
+                                Notification.EXTRA_CONTAINS_CUSTOM_VIEW),
+                        updatedNotification.extras.getBoolean(
+                                Notification.EXTRA_CONTAINS_CUSTOM_VIEW));
                 applyInPlace = compareRemoteViews(cachedContentView, newContentView)
                         && compareRemoteViews(cachedBigContentView, newBigContentView)
                         && compareRemoteViews(cachedHeadsUpContentView, newHeadsUpContentView)
-                        && compareRemoteViews(cachedPublicContentView, newPublicNotification);
+                        && compareRemoteViews(cachedPublicContentView, newPublicNotification)
+                        && sameCustomView;
                 cachedPublicContentView = newPublicNotification;
                 cachedHeadsUpContentView = newHeadsUpContentView;
                 cachedBigContentView = newBigContentView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 7346bec..fe84d813 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -49,9 +49,7 @@
     private int mClipTopAmount;
     private int mActualHeight;
     private boolean mExposed;
-    private RadioButton mApplyToTopic;
     private SeekBar mSeekBar;
-    private Notification.Topic mTopic;
     private INotificationManager mINotificationManager;
     private int mStartingImportance;
 
@@ -109,24 +107,9 @@
         mStartingImportance = importance;
         mINotificationManager = INotificationManager.Stub.asInterface(
                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
-        mTopic = sbn.getNotification().getTopic() == null
-                ? new Notification.Topic(Notification.TOPIC_DEFAULT, mContext.getString(
-                com.android.internal.R.string.default_notification_topic_label))
-                : sbn.getNotification().getTopic();
-        boolean doesUserUseTopics = false;
-        try {
-            doesUserUseTopics =
-                    mINotificationManager.doesUserUseTopics(sbn.getPackageName(), sbn.getUid());
-        } catch (RemoteException e) {}
-        final boolean userUsesTopics = doesUserUseTopics;
 
-        mApplyToTopic = (RadioButton) row.findViewById(R.id.apply_to_topic);
-        if (userUsesTopics) {
-            mApplyToTopic.setChecked(true);
-        }
-        final View applyToApp = row.findViewById(R.id.apply_to_app);
-        final TextView topicSummary = ((TextView) row.findViewById(R.id.summary));
-        final TextView topicTitle = ((TextView) row.findViewById(R.id.title));
+        final TextView importanceSummary = ((TextView) row.findViewById(R.id.summary));
+        final TextView importanceTitle = ((TextView) row.findViewById(R.id.title));
         mSeekBar = (SeekBar) row.findViewById(R.id.seekbar);
         boolean systemApp = false;
         try {
@@ -156,12 +139,6 @@
                 updateTitleAndSummary(progress);
                 if (fromUser) {
                     MetricsLogger.action(mContext, MetricsEvent.ACTION_MODIFY_IMPORTANCE_SLIDER);
-                    if (userUsesTopics) {
-                        mApplyToTopic.setVisibility(View.VISIBLE);
-                        mApplyToTopic.setText(
-                                mContext.getString(R.string.apply_to_topic, mTopic.getLabel()));
-                        applyToApp.setVisibility(View.VISIBLE);
-                    }
                 }
             }
 
@@ -178,29 +155,29 @@
             private void updateTitleAndSummary(int progress) {
                 switch (progress) {
                     case NotificationListenerService.Ranking.IMPORTANCE_NONE:
-                        topicSummary.setText(mContext.getString(
+                        importanceSummary.setText(mContext.getString(
                                 R.string.notification_importance_blocked));
-                        topicTitle.setText(mContext.getString(R.string.blocked_importance));
+                        importanceTitle.setText(mContext.getString(R.string.blocked_importance));
                         break;
                     case NotificationListenerService.Ranking.IMPORTANCE_LOW:
-                        topicSummary.setText(mContext.getString(
+                        importanceSummary.setText(mContext.getString(
                                 R.string.notification_importance_low));
-                        topicTitle.setText(mContext.getString(R.string.low_importance));
+                        importanceTitle.setText(mContext.getString(R.string.low_importance));
                         break;
                     case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
-                        topicSummary.setText(mContext.getString(
+                        importanceSummary.setText(mContext.getString(
                                 R.string.notification_importance_default));
-                        topicTitle.setText(mContext.getString(R.string.default_importance));
+                        importanceTitle.setText(mContext.getString(R.string.default_importance));
                         break;
                     case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
-                        topicSummary.setText(mContext.getString(
+                        importanceSummary.setText(mContext.getString(
                                 R.string.notification_importance_high));
-                        topicTitle.setText(mContext.getString(R.string.high_importance));
+                        importanceTitle.setText(mContext.getString(R.string.high_importance));
                         break;
                     case NotificationListenerService.Ranking.IMPORTANCE_MAX:
-                        topicSummary.setText(mContext.getString(
+                        importanceSummary.setText(mContext.getString(
                                 R.string.notification_importance_max));
-                        topicTitle.setText(mContext.getString(R.string.max_importance));
+                        importanceTitle.setText(mContext.getString(R.string.max_importance));
                         break;
                 }
             }
@@ -213,8 +190,7 @@
         MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
                 progress - mStartingImportance);
         try {
-            mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(),
-                    mApplyToTopic.isChecked() ? mTopic : null, progress);
+            mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(), progress);
         } catch (RemoteException e) {
             // :(
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java
new file mode 100644
index 0000000..4491ebd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java
@@ -0,0 +1,209 @@
+/*
+ * 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.statusbar;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+
+public class NotificationSettingsIconRow extends FrameLayout implements View.OnClickListener {
+
+    public interface SettingsIconRowListener {
+        /**
+         * Called when the gear behind a notification is touched.
+         */
+        public void onGearTouched(ExpandableNotificationRow row);
+    }
+
+    private ExpandableNotificationRow mParent;
+    private AlphaOptimizedImageView mGearIcon;
+    private float mHorizSpaceForGear;
+    private SettingsIconRowListener mListener;
+
+    private ValueAnimator mFadeAnimator;
+    private boolean mSettingsFadedIn = false;
+    private boolean mAnimating = false;
+    private boolean mOnLeft = true;
+
+    public NotificationSettingsIconRow(Context context) {
+        this(context, null);
+    }
+
+    public NotificationSettingsIconRow(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public NotificationSettingsIconRow(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public NotificationSettingsIconRow(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mGearIcon = (AlphaOptimizedImageView) findViewById(R.id.gear_icon);
+        mGearIcon.setOnClickListener(this);
+        setOnClickListener(this);
+        mHorizSpaceForGear =
+                getResources().getDimensionPixelOffset(R.dimen.notification_gear_width);
+        resetState();
+    }
+
+    public void setGearListener(SettingsIconRowListener listener) {
+        mListener = listener;
+    }
+
+    public void setNotificationRowParent(ExpandableNotificationRow parent) {
+        mParent = parent;
+    }
+
+    public ExpandableNotificationRow getNotificationParent() {
+        return mParent;
+    }
+
+    public void resetState() {
+        setGearAlpha(0f);
+        mAnimating = false;
+        setIconLocation(true /* on left */);
+    }
+
+    private void setGearAlpha(float alpha) {
+        if (alpha == 0) {
+            mSettingsFadedIn = false; // Can fade in again once it's gone.
+            mGearIcon.setVisibility(View.INVISIBLE);
+        } else {
+            if (alpha == 1) {
+                mSettingsFadedIn = true;
+            }
+            mGearIcon.setVisibility(View.VISIBLE);
+        }
+        mGearIcon.setAlpha(alpha);
+    }
+
+    /**
+     * Returns the horizontal space in pixels required to display the gear behind a notification.
+     */
+    public float getSpaceForGear() {
+        return mHorizSpaceForGear;
+    }
+
+    /**
+     * Indicates whether the gear is visible at 1 alpha. Does not indicate
+     * if entire view is visible.
+     */
+    public boolean isVisible() {
+        return mSettingsFadedIn;
+    }
+
+    public void cancelFadeAnimator() {
+        if (mFadeAnimator != null) {
+            mFadeAnimator.cancel();
+        }
+    }
+
+    public void updateSettingsIcons(final float transX, final float size) {
+        if (mAnimating || (mGearIcon.getAlpha() == 0)) {
+            // Don't adjust when animating or settings aren't visible
+            return;
+        }
+        setIconLocation(transX > 0 /* fromLeft */);
+        final float fadeThreshold = size * 0.3f;
+        final float absTrans = Math.abs(transX);
+        float desiredAlpha = 0;
+
+        if (absTrans <= fadeThreshold) {
+            desiredAlpha = 1;
+        } else {
+            desiredAlpha = 1 - ((absTrans - fadeThreshold) / (size - fadeThreshold));
+        }
+        setGearAlpha(desiredAlpha);
+    }
+
+    public void fadeInSettings(final boolean fromLeft, final float transX,
+            final float notiThreshold) {
+        setIconLocation(transX > 0 /* fromLeft */);
+        mFadeAnimator = ValueAnimator.ofFloat(mGearIcon.getAlpha(), 1);
+        mFadeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                final float absTrans = Math.abs(transX);
+
+                boolean pastGear = (fromLeft && transX <= notiThreshold)
+                        || (!fromLeft && absTrans <= notiThreshold);
+                if (pastGear && !mSettingsFadedIn) {
+                    setGearAlpha((float) animation.getAnimatedValue());
+                }
+            }
+        });
+        mFadeAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                super.onAnimationCancel(animation);
+                mAnimating = false;
+                mSettingsFadedIn = false;
+            }
+
+            @Override
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
+                mAnimating = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                mAnimating = false;
+                mSettingsFadedIn = true;
+            }
+        });
+        mFadeAnimator.setInterpolator(Interpolators.ALPHA_IN);
+        mFadeAnimator.setDuration(200);
+        mFadeAnimator.start();
+    }
+
+    private void setIconLocation(boolean onLeft) {
+        if (onLeft == mOnLeft) {
+            // Same side? Do nothing.
+            return;
+        }
+
+        setTranslationX(onLeft ? 0 : (mParent.getWidth() - mHorizSpaceForGear));
+        mOnLeft = onLeft;
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.gear_icon) {
+            if (mListener != null) {
+                mListener.onGearTouched(mParent);
+            }
+        } else {
+            // Do nothing when the background is touched.
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
new file mode 100644
index 0000000..4f3c61e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -0,0 +1,124 @@
+/*
+ * 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.statusbar.phone;
+
+import android.app.ActivityManager;
+import android.app.IWallpaperManager;
+import android.app.IWallpaperManagerCallback;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import libcore.io.IoUtils;
+
+/**
+ * Manages the lockscreen wallpaper.
+ */
+public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implements Runnable {
+
+    private static final String TAG = "LockscreenWallpaper";
+
+    private final Context mContext;
+    private final PhoneStatusBar mBar;
+    private final IWallpaperManager mService;
+    private final Handler mH;
+
+    private boolean mCached;
+    private Bitmap mCache;
+    private int mUserId;
+
+    public LockscreenWallpaper(Context ctx, PhoneStatusBar bar, Handler h) {
+        mContext = ctx;
+        mBar = bar;
+        mH = h;
+        mService = IWallpaperManager.Stub.asInterface(
+                ServiceManager.getService(Context.WALLPAPER_SERVICE));
+        mUserId = ActivityManager.getCurrentUser();
+
+        try {
+            mService.setLockWallpaperCallback(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "System dead?" + e);
+        }
+    }
+
+    public Bitmap getBitmap() {
+        try {
+            if (mCached) {
+                return mCache;
+            }
+            if (!mService.isWallpaperSupported(mContext.getOpPackageName())) {
+                mCached = true;
+                mCache = null;
+                return null;
+            }
+            ParcelFileDescriptor fd = mService.getWallpaper(null, WallpaperManager.FLAG_SET_LOCK,
+                    new Bundle(), mUserId);
+            if (fd != null) {
+                try {
+                    BitmapFactory.Options options = new BitmapFactory.Options();
+                    mCache = BitmapFactory.decodeFileDescriptor(
+                            fd.getFileDescriptor(), null, options);
+                    mCached = true;
+                    return mCache;
+                } catch (OutOfMemoryError e) {
+                    Log.w(TAG, "Can't decode file", e);
+                    return null;
+                } finally {
+                    IoUtils.closeQuietly(fd);
+                }
+            } else {
+                mCached = true;
+                mCache = null;
+                return null;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "System dead?" + e);
+            return null;
+        }
+    }
+
+    public void setUser(int user) {
+        if (user != mUserId) {
+            mCached = false;
+            mUserId = user;
+        }
+    }
+
+    @Override
+    public void onWallpaperChanged() {
+        // Called on Binder thread.
+        mH.removeCallbacks(this);
+        mH.post(this);
+    }
+
+    @Override
+    public void run() {
+        // Called in response to onWallpaperChanged on the main thread.
+        mCached = false;
+        mCache = null;
+        getBitmap();
+        mBar.updateMediaMetaData(true /* metaDataChanged */, true /* allowEnterAnimation */);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 6698076..e53f044 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -512,6 +512,11 @@
                         }
                     });
                 }
+
+                @Override
+                public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
+                        throws RemoteException {
+                }
             });
         } catch (RemoteException e) {
             Log.e(TAG, "Failed registering docked stack exists listener", e);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 401d405..1089852 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -23,6 +23,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
+import android.app.IWallpaperManagerCallback;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
@@ -115,7 +116,7 @@
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.qs.QSDetail;
+import com.android.systemui.qs.QSContainer;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.recents.events.EventBus;
@@ -248,9 +249,7 @@
     private static final boolean ONLY_CORE_APPS;
 
     /** If true, the lockscreen will show a distinct wallpaper */
-    private static final boolean ENABLE_LOCKSCREEN_WALLPAPER =
-            !ActivityManager.isLowRamDeviceStatic()
-                    && SystemProperties.getBoolean("debug.lockscreen_wallpaper", false);
+    private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
 
     /* If true, the device supports freeform window management.
      * This affects the status bar UI. */
@@ -296,6 +295,7 @@
     AccessibilityController mAccessibilityController;
     FingerprintUnlockController mFingerprintUnlockController;
     LightStatusBarController mLightStatusBarController;
+    private LockscreenWallpaper mLockscreenWallpaper;
 
     int mNaturalBarHeight = -1;
 
@@ -746,6 +746,7 @@
         mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
                 R.id.notification_stack_scroller);
         mStackScroller.setLongPressListener(getNotificationLongClicker());
+        mStackScroller.setGearDisplayedListener(getGearDisplayedListener());
         mStackScroller.setPhoneStatusBar(this);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setHeadsUpManager(mHeadsUpManager);
@@ -792,6 +793,10 @@
                 mKeyguardBottomArea.getLockIcon());
         mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
 
+        if (ENABLE_LOCKSCREEN_WALLPAPER) {
+            mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
+        }
+
         // set the initial view visibility
         setAreThereNotifications();
 
@@ -867,13 +872,12 @@
                     mCastController, mFlashlightController,
                     mUserSwitcherController, mUserInfoController, mKeyguardMonitor,
                     mSecurityController, mBatteryController, mIconController);
-            mQSPanel.setHost(qsh);
             mQSPanel.setTiles(qsh.getTiles());
             mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
             mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
-            mHeader.setQSPanel(mQSPanel);
-            QSDetail qsDetail = (QSDetail) mStatusBarWindow.findViewById(R.id.qs_detail);
-            qsDetail.setHost(qsh);
+            QSContainer qsContainer = (QSContainer) mStatusBarWindow.findViewById(
+                    R.id.quick_settings_container);
+            qsContainer.setHost(qsh);
             qsh.addCallback(new QSTileHost.Callback() {
                 @Override
                 public void onTilesChanged() {
@@ -1819,7 +1823,7 @@
     };
 
     /**
-     * Refresh or remove lockscreen artwork from media metadata.
+     * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
      */
     public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
         if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
@@ -1847,10 +1851,7 @@
             }
         }
         if (ENABLE_LOCKSCREEN_WALLPAPER && artworkBitmap == null) {
-            // TODO: use real lockscreen wallpaper.
-            WallpaperManager wallpaperManager = mContext
-                    .getSystemService(WallpaperManager.class);
-            artworkBitmap = wallpaperManager.getBitmap();
+            artworkBitmap = mLockscreenWallpaper.getBitmap();
         }
 
         final boolean hasArtwork = artworkBitmap != null;
@@ -3084,10 +3085,6 @@
             else if (Intent.ACTION_SCREEN_ON.equals(action)) {
                 notifyNavigationBarScreenOn(true);
             }
-            else if (ENABLE_LOCKSCREEN_WALLPAPER
-                    && Intent.ACTION_WALLPAPER_CHANGED.equals(action)) {
-                updateMediaMetaData(true, true);
-            }
         }
     };
 
@@ -3173,6 +3170,7 @@
         resetUserSetupObserver();
         setControllerUsers();
         clearCurrentMediaNotification();
+        mLockscreenWallpaper.setUser(newUserId);
         updateMediaMetaData(true, false);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index df5a622..6550c87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -456,11 +456,9 @@
                 mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_landscape,
                         mContext.getString(R.string.accessibility_rotation_lock_on_landscape));
             }
+            mIconController.setIconVisibility(mSlotRotate, true);
         } else {
-            mIconController.setIcon(mSlotRotate, portrait
-                    ? R.drawable.stat_sys_auto_rotate_portrait
-                    : R.drawable.stat_sys_auto_rotate_landscape,
-                    mContext.getString(R.string.accessibility_rotation_lock_off));
+            mIconController.setIconVisibility(mSlotRotate, false);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 2af2009..80afb9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -57,7 +57,7 @@
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.DisplayController;
+import com.android.systemui.statusbar.policy.NightModeController;
 import com.android.systemui.statusbar.policy.FlashlightController;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -68,7 +68,7 @@
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.tuner.ColorMatrixTile;
+import com.android.systemui.tuner.NightModeTile;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -108,7 +108,7 @@
     private final TileServices mServices;
 
     private final List<Callback> mCallbacks = new ArrayList<>();
-    private final DisplayController mDisplayController;
+    private final NightModeController mNightModeController;
     private final AutoTileManager mAutoTiles;
     private final ManagedProfileController mProfileController;
     private View mHeader;
@@ -137,7 +137,7 @@
         mSecurity = security;
         mBattery = battery;
         mIconController = iconController;
-        mDisplayController = new DisplayController(mContext);
+        mNightModeController = new NightModeController(mContext, true);
         mProfileController = new ManagedProfileController(this);
 
         final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName(),
@@ -292,8 +292,8 @@
         return mIconController;
     }
 
-    public DisplayController getDisplayController() {
-        return mDisplayController;
+    public NightModeController getNightModeController() {
+        return mNightModeController;
     }
 
     public ManagedProfileController getManagedProfileController() {
@@ -422,8 +422,8 @@
         else if (tileSpec.equals("user")) return new UserTile(this);
         else if (tileSpec.equals("battery")) return new BatteryTile(this);
         else if (tileSpec.equals("saver")) return new DataSaverTile(this);
-        else if (tileSpec.equals(ColorMatrixTile.COLOR_MATRIX_SPEC))
-            return new ColorMatrixTile(this);
+        else if (tileSpec.equals(NightModeTile.NIGHT_MODE_SPEC))
+            return new NightModeTile(this);
         // Intent tiles.
         else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
         else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this,tileSpec);
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 bd5bac2..ab8067d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -34,6 +34,7 @@
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
+import com.android.systemui.qs.QSAnimator;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.QuickQSPanel;
@@ -50,7 +51,7 @@
 
     private static final String TAG = "QuickStatusBarHeader";
 
-    private static final float EXPAND_INDICATOR_THRESHOLD = .8f;
+    private static final float EXPAND_INDICATOR_THRESHOLD = .93f;
 
     private ActivityStarter mActivityStarter;
     private NextAlarmController mNextAlarmController;
@@ -89,6 +90,7 @@
     private TouchAnimator mFirstHalfAnimator;
     private TouchAnimator mDateSizeAnimator;
     private TouchAnimator mAlarmTranslation;
+    private TouchAnimator mSettingsAlpha;
     private float mExpansionAmount;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
@@ -164,18 +166,16 @@
         mAnimator = new TouchAnimator.Builder()
                 .addFloat(mSettingsContainer, "translationY", -mGearTranslation, 0)
                 .addFloat(mMultiUserSwitch, "translationY", -mGearTranslation, 0)
-                .addFloat(mSettingsButton, "rotation", -90, 0)
                 .setListener(this)
                 .build();
         mSecondHalfAnimator = new TouchAnimator.Builder()
-                .addFloat(mSettingsButton, "rotation", -90, 0)
+                .addFloat(mSettingsButton, "rotation", -180, 0)
                 .addFloat(mAlarmStatus, "alpha", 0, 1)
                 .addFloat(mEmergencyOnly, "alpha", 0, 1)
                 .setStartDelay(.5f)
                 .build();
         mFirstHalfAnimator = new TouchAnimator.Builder()
                 .addFloat(mAlarmStatusCollapsed, "alpha", 1, 0)
-                .addFloat(mHeaderQsPanel, "alpha", 1, 0)
                 .setEndDelay(.5f)
                 .build();
         mDateSizeAnimator = new TouchAnimator.Builder()
@@ -183,6 +183,11 @@
                 .addFloat(mDateTimeGroup, "scaleY", 1, mDateScaleFactor)
                 .setStartDelay(.36f)
                 .build();
+        mSettingsAlpha = new TouchAnimator.Builder()
+                .addFloat(mSettingsContainer, "alpha", 0, 1)
+                .addFloat(mMultiUserSwitch, "alpha", 0, 1)
+                .setStartDelay(QSAnimator.EXPANDED_TILE_DELAY)
+                .build();
     }
 
     @Override
@@ -221,6 +226,7 @@
         mFirstHalfAnimator.setPosition(headerExpansionFraction);
         mDateSizeAnimator.setPosition(headerExpansionFraction);
         mAlarmTranslation.setPosition(headerExpansionFraction);
+        mSettingsAlpha.setPosition(headerExpansionFraction);
 
         updateAlarmVisibilities();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DisplayController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DisplayController.java
deleted file mode 100644
index d47050c..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DisplayController.java
+++ /dev/null
@@ -1,193 +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.statusbar.policy;
-
-import libcore.util.Objects;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.provider.Settings;
-
-import com.android.systemui.R;
-import com.android.systemui.tuner.TunerService;
-
-import java.util.ArrayList;
-
-public class DisplayController implements TunerService.Tunable {
-
-    public static final String COLOR_MATRIX_CUSTOM_ENABLED = "tuner_color_custom_enabled";
-    public static final String COLOR_MATRIX_CUSTOM_VALUES = "tuner_color_custom_values";
-
-    public static final String COLOR_STATE = "sysui_color_matrix_state";
-
-    public static final int COLOR_STATE_DISABLED = 0;
-    public static final int COLOR_STATE_ENABLED = 1;
-    public static final int COLOR_STATE_AUTO = 2;
-
-    public static final String AUTO_STRING = "auto_mode";
-    public static final String NONE_STRING = "none";
-
-    public static final int AUTO_INDEX = 2;
-    public static final int CUSTOM_INDEX = 3;
-
-    // Night mode ~= 3400 K
-    private static final float[] NIGHT_VALUES = new float[] {
-        1, 0,     0,     0,
-        0, .754f, 0,     0,
-        0, 0,     .516f, 0,
-        0, 0,     0,     1,
-    };
-    public static final float[] IDENTITY_MATRIX = new float[] {
-        1, 0, 0, 0,
-        0, 1, 0, 0,
-        0, 0, 1, 0,
-        0, 0, 0, 1,
-    };
-
-    private final ArrayList<Listener> mListeners = new ArrayList<>();
-
-    private final Context mContext;
-
-    private String mCurrentValue;
-    private boolean mListening;
-
-    public DisplayController(Context context) {
-        mContext = context;
-        TunerService.get(mContext).addTunable(this, COLOR_STATE,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX);
-    }
-
-    public void addListener(Listener listener) {
-        mListeners.add(listener);
-        listener.onCurrentMatrixChanged();
-    }
-
-    public void removeListener(Listener listener) {
-        mListeners.remove(listener);
-    }
-
-    public boolean isEnabled() {
-        return TunerService.get(mContext).getValue(COLOR_STATE, COLOR_STATE_DISABLED)
-                != COLOR_STATE_DISABLED;
-    }
-
-    public boolean isAuto() {
-        return mListening;
-    }
-
-    public void setAuto(boolean auto) {
-        TunerService.get(mContext).setValue(COLOR_STATE, auto ? COLOR_STATE_AUTO
-                : COLOR_STATE_DISABLED);
-    }
-
-    public boolean isCustomSet() {
-        return isCustomEnabled() && Objects.equal(getCurrentMatrix(), getCustomValues());
-    }
-
-    public String getCurrentMatrix() {
-        return mCurrentValue;
-    }
-
-    public String getCustomValues() {
-        return TunerService.get(mContext).getValue(COLOR_MATRIX_CUSTOM_VALUES);
-    }
-
-    public boolean isCustomEnabled() {
-        return TunerService.get(mContext).getValue(COLOR_MATRIX_CUSTOM_ENABLED, 0) != 0;
-    }
-
-    @Override
-    public void onTuningChanged(String key, String newValue) {
-        if (Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX.equals(key)) {
-            mCurrentValue = newValue;
-            for (int i = 0; i < mListeners.size(); i++) {
-                mListeners.get(i).onCurrentMatrixChanged();
-            }
-        } else if (COLOR_STATE.equals(key)) {
-            final boolean listening = newValue != null
-                    && Integer.parseInt(newValue) == COLOR_STATE_AUTO;
-            if (listening && !mListening) {
-                mListening = true;
-                mContext.registerReceiver(mReceiver,
-                        new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
-                updateNightMode();
-            } else if (!listening && mListening) {
-                mListening = false;
-                mContext.unregisterReceiver(mReceiver);
-            }
-            for (int i = 0; i < mListeners.size(); i++) {
-                mListeners.get(i).onCurrentMatrixChanged();
-            }
-        }
-    }
-
-    private void updateNightMode() {
-        final int uiMode = mContext.getResources().getConfiguration().uiMode;
-        final boolean isNightMode = (uiMode & Configuration.UI_MODE_NIGHT_MASK)
-                == Configuration.UI_MODE_NIGHT_YES;
-        String value = null;
-        if (isNightMode) {
-            value = toString(NIGHT_VALUES);
-        }
-        TunerService.get(mContext).setValue(Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
-                value);
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
-                updateNightMode();
-            }
-        }
-    };
-
-    public interface Listener {
-        void onCurrentMatrixChanged();
-    }
-
-    public static String[] getColorTransforms(Context context) {
-        return new String[] {
-                NONE_STRING,
-                toString(NIGHT_VALUES),
-                AUTO_STRING, // Blank spot for auto values
-                null, // Blank spot for custom values
-        };
-    }
-
-    public static CharSequence[] getColorTitles(Context context) {
-        // TODO: Move to string array resource.
-        return new CharSequence[]{
-                context.getString(R.string.color_matrix_none),
-                context.getString(R.string.color_matrix_night),
-                context.getString(R.string.color_matrix_auto),
-                context.getString(R.string.color_matrix_custom),
-        };
-    }
-
-    public static String toString(float[] values) {
-        StringBuilder builder = new StringBuilder();
-        for (int i = 0; i < values.length; i++) {
-            if (builder.length() != 0) {
-                builder.append(',');
-            }
-            builder.append(values[i]);
-        }
-        return builder.toString();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
index 500d603..047f14d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java
@@ -21,7 +21,6 @@
     void removeCallback(Callback callback);
     boolean isHotspotEnabled();
     void setHotspotEnabled(boolean enabled);
-    boolean isTetheringAllowed();
 
     public interface Callback {
         void onHotspotChanged(boolean enabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 07b7409..f03d9e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -16,15 +16,12 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
-import android.os.UserHandle;
-import android.os.UserManager;
 import android.util.Log;
 
 import java.io.FileDescriptor;
@@ -40,8 +37,6 @@
     private final Receiver mReceiver = new Receiver();
     private final ConnectivityManager mConnectivityManager;
     private final Context mContext;
-    private final UserManager mUserManager;
-    private final int mCurrentUser;
 
     private int mHotspotState;
 
@@ -49,8 +44,6 @@
         mContext = context;
         mConnectivityManager = (ConnectivityManager) context.getSystemService(
                 Context.CONNECTIVITY_SERVICE);
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        mCurrentUser = ActivityManager.getCurrentUser();
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -95,12 +88,6 @@
         return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED;
     }
 
-    @Override
-    public boolean isTetheringAllowed() {
-        return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING,
-                UserHandle.of(mCurrentUser));
-    }
-
     static final class OnStartTetheringCallback extends
             ConnectivityManager.OnStartTetheringCallback {
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 401943e..29a8981 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -21,7 +21,6 @@
     boolean setLocationEnabled(boolean enabled);
     void addSettingsChangedCallback(LocationSettingsChangeCallback cb);
     void removeSettingsChangedCallback(LocationSettingsChangeCallback cb);
-    boolean isUserLocationRestricted();
 
     /**
      * A callback for change in location settings (the user has enabled/disabled location).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 436a40d..8d84be4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -52,7 +52,6 @@
 
     private AppOpsManager mAppOpsManager;
     private StatusBarManager mStatusBarManager;
-    private final int mCurrentUser;
 
     private boolean mAreActiveLocationRequests;
 
@@ -74,7 +73,6 @@
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
         mStatusBarManager
                 = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
-        mCurrentUser = ActivityManager.getCurrentUser();
 
         // Examine the current location state and initialize the status view.
         updateActiveLocationRequests();
@@ -105,6 +103,10 @@
      * @return true if attempt to change setting was successful.
      */
     public boolean setLocationEnabled(boolean enabled) {
+        int currentUserId = ActivityManager.getCurrentUser();
+        if (isUserLocationRestricted(currentUserId)) {
+            return false;
+        }
         final ContentResolver cr = mContext.getContentResolver();
         // When enabling location, a user consent dialog will pop up, and the
         // setting won't be fully enabled until the user accepts the agreement.
@@ -113,7 +115,7 @@
         // QuickSettings always runs as the owner, so specifically set the settings
         // for the current foreground user.
         return Settings.Secure
-                .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, mCurrentUser);
+                .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, currentUserId);
     }
 
     /**
@@ -131,10 +133,10 @@
     /**
      * Returns true if the current user is restricted from using location.
      */
-    public boolean isUserLocationRestricted() {
+    private boolean isUserLocationRestricted(int userId) {
         final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         return um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION,
-                UserHandle.of(mCurrentUser));
+                UserHandle.of(userId));
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NightModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NightModeController.java
new file mode 100644
index 0000000..0b1911b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NightModeController.java
@@ -0,0 +1,250 @@
+/*
+ * 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.statusbar.policy;
+
+import libcore.util.Objects;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.opengl.Matrix;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.util.MathUtils;
+
+import com.android.systemui.tuner.TunerService;
+
+import java.util.ArrayList;
+
+/**
+ * Listens for changes to twilight from the TwilightService.
+ *
+ * Also pushes the current matrix to accessibility based on the current twilight
+ * and various tuner settings.
+ */
+public class NightModeController implements TunerService.Tunable {
+
+    public static final String NIGHT_MODE_ADJUST_TINT = "tuner_night_mode_adjust_tint";
+    private static final String COLOR_MATRIX_CUSTOM_VALUES = "tuner_color_custom_values";
+
+    private static final String ACTION_TWILIGHT_CHANGED = "android.intent.action.TWILIGHT_CHANGED";
+
+    private static final String EXTRA_IS_NIGHT = "isNight";
+    private static final String EXTRA_AMOUNT = "amount";
+
+    // Night mode ~= 3400 K
+    private static final float[] NIGHT_VALUES = new float[] {
+        1, 0,     0,     0,
+        0, .754f, 0,     0,
+        0, 0,     .516f, 0,
+        0, 0,     0,     1,
+    };
+    public static final float[] IDENTITY_MATRIX = new float[] {
+        1, 0, 0, 0,
+        0, 1, 0, 0,
+        0, 0, 1, 0,
+        0, 0, 0, 1,
+    };
+
+    private final ArrayList<Listener> mListeners = new ArrayList<>();
+
+    private final Context mContext;
+
+    // This is whether or not this is the main NightMode controller in SysUI that should be
+    // updating relevant color matrixes or if its in the tuner process getting current state
+    // for UI.
+    private final boolean mUpdateMatrix;
+
+    private float[] mCustomMatrix;
+    private boolean mListening;
+    private boolean mAdjustTint;
+
+    private boolean mIsNight;
+    private float mAmount;
+    private boolean mIsAuto;
+
+    public NightModeController(Context context) {
+        this(context, false);
+    }
+
+    public NightModeController(Context context, boolean updateMatrix) {
+        mContext = context;
+        mUpdateMatrix = updateMatrix;
+        TunerService.get(mContext).addTunable(this, NIGHT_MODE_ADJUST_TINT,
+                COLOR_MATRIX_CUSTOM_VALUES, Secure.TWILIGHT_MODE);
+    }
+
+    public void setNightMode(boolean isNight) {
+        if (mIsAuto) {
+            if (mIsNight != isNight) {
+                TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, isNight
+                        ? Secure.TWILIGHT_MODE_AUTO_OVERRIDE_ON
+                        : Secure.TWILIGHT_MODE_AUTO_OVERRIDE_OFF);
+            } else {
+                TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE,
+                        Secure.TWILIGHT_MODE_AUTO);
+            }
+        } else {
+            TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, isNight
+                    ? Secure.TWILIGHT_MODE_LOCKED_ON : Secure.TWILIGHT_MODE_LOCKED_OFF);
+        }
+    }
+
+    public void setAuto(boolean auto) {
+        mIsAuto = auto;
+        if (auto) {
+            TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, Secure.TWILIGHT_MODE_AUTO);
+        } else {
+            // Lock into the current state
+            TunerService.get(mContext).setValue(Secure.TWILIGHT_MODE, mIsNight
+                    ? Secure.TWILIGHT_MODE_LOCKED_ON : Secure.TWILIGHT_MODE_LOCKED_OFF);
+        }
+    }
+
+    public boolean isAuto() {
+        return mIsAuto;
+    }
+
+    public void setAdjustTint(Boolean newValue) {
+        TunerService.get(mContext).setValue(NIGHT_MODE_ADJUST_TINT, ((Boolean) newValue) ? 1 : 0);
+    }
+
+    public void addListener(Listener listener) {
+        mListeners.add(listener);
+        listener.onNightModeChanged();
+        updateListening();
+    }
+
+    public void removeListener(Listener listener) {
+        mListeners.remove(listener);
+        updateListening();
+    }
+
+    private void updateListening() {
+        boolean shouldListen = mListeners.size() != 0 || (mUpdateMatrix && mAdjustTint);
+        if (shouldListen == mListening) return;
+        mListening = shouldListen;
+        if (mListening) {
+            mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_TWILIGHT_CHANGED));
+        } else {
+            mContext.unregisterReceiver(mReceiver);
+        }
+    }
+
+    public boolean isEnabled() {
+        if (!mListening) {
+            updateNightMode(mContext.registerReceiver(null,
+                    new IntentFilter(ACTION_TWILIGHT_CHANGED)));
+        }
+        return mIsNight;
+    }
+
+    public String getCustomValues() {
+        return TunerService.get(mContext).getValue(COLOR_MATRIX_CUSTOM_VALUES);
+    }
+
+    public void setCustomValues(String values) {
+        TunerService.get(mContext).setValue(COLOR_MATRIX_CUSTOM_VALUES, values);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (COLOR_MATRIX_CUSTOM_VALUES.equals(key)) {
+            mCustomMatrix = newValue != null ? toValues(newValue) : null;
+            updateCurrentMatrix();
+        } else if (NIGHT_MODE_ADJUST_TINT.equals(key)) {
+            mAdjustTint = newValue == null || Integer.parseInt(newValue) != 0;
+            updateListening();
+            updateCurrentMatrix();
+        } else if (Secure.TWILIGHT_MODE.equals(key)) {
+            mIsAuto = newValue != null && Integer.parseInt(newValue) >= Secure.TWILIGHT_MODE_AUTO;
+        }
+    }
+
+    private void updateCurrentMatrix() {
+        if (!mUpdateMatrix) return;
+        if ((!mAdjustTint || mAmount == 0) && mCustomMatrix == null) {
+            TunerService.get(mContext).setValue(Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
+            return;
+        }
+        float[] values = scaleValues(IDENTITY_MATRIX, NIGHT_VALUES, mAdjustTint ? mAmount : 0);
+        if (mCustomMatrix != null) {
+            values = multiply(values, mCustomMatrix);
+        }
+        TunerService.get(mContext).setValue(Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
+                toString(values));
+    }
+
+    private void updateNightMode(Intent intent) {
+        mIsNight = intent.getBooleanExtra(EXTRA_IS_NIGHT, false);
+        mAmount = intent.getFloatExtra(EXTRA_AMOUNT, 0);
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (ACTION_TWILIGHT_CHANGED.equals(intent.getAction())) {
+                updateNightMode(intent);
+                updateCurrentMatrix();
+                for (int i = 0; i < mListeners.size(); i++) {
+                    mListeners.get(i).onNightModeChanged();
+                }
+            }
+        }
+    };
+
+    public interface Listener {
+        void onNightModeChanged();
+        void onTwilightAutoChanged();
+    }
+
+    private static float[] multiply(float[] matrix, float[] other) {
+        if (matrix == null) {
+            return other;
+        }
+        float[] result = new float[16];
+        Matrix.multiplyMM(result, 0, matrix, 0, other, 0);
+        return result;
+    }
+
+    private float[] scaleValues(float[] identityMatrix, float[] nightValues, float amount) {
+        float[] values = new float[identityMatrix.length];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = MathUtils.lerp(identityMatrix[i], nightValues[i], amount);
+        }
+        return values;
+    }
+
+    public static String toString(float[] values) {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < values.length; i++) {
+            if (builder.length() != 0) {
+                builder.append(',');
+            }
+            builder.append(values[i]);
+        }
+        return builder.toString();
+    }
+
+    public static float[] toValues(String customValues) {
+        String[] strValues = customValues.split(",");
+        float[] values = new float[strValues.length];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = Float.parseFloat(strValues[i]);
+        }
+        return values;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 6ca7dc8..13369f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -210,12 +210,16 @@
                     }
                 }
 
+                boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction(
+                                UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
                 boolean currentUserCanCreateUsers = currentUserInfo != null
                         && (currentUserInfo.isAdmin()
-                                || currentUserInfo.id == UserHandle.USER_SYSTEM);
-                boolean canCreateGuest = (currentUserCanCreateUsers || addUsersWhenLocked)
+                                || currentUserInfo.id == UserHandle.USER_SYSTEM)
+                        && systemCanCreateUsers;
+                boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked;
+                boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers)
                         && guestRecord == null;
-                boolean canCreateUser = (currentUserCanCreateUsers || addUsersWhenLocked)
+                boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers)
                         && mUserManager.canAddMoreUsers();
                 boolean createIsRestricted = !addUsersWhenLocked;
 
@@ -225,7 +229,7 @@
                             guestRecord = new UserRecord(null /* info */, null /* picture */,
                                     true /* isGuest */, false /* isCurrent */,
                                     false /* isAddUser */, createIsRestricted);
-                            checkIfAddUserDisallowed(guestRecord);
+                            checkIfAddUserDisallowedByAdminOnly(guestRecord);
                             records.add(guestRecord);
                         }
                     } else {
@@ -238,7 +242,7 @@
                     UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
                             false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
                             createIsRestricted);
-                    checkIfAddUserDisallowed(addUserRecord);
+                    checkIfAddUserDisallowedByAdminOnly(addUserRecord);
                     records.add(addUserRecord);
                 }
 
@@ -615,10 +619,11 @@
         }
     }
 
-    private void checkIfAddUserDisallowed(UserRecord record) {
+    private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) {
         EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
                 UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser());
-        if (admin != null) {
+        if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext,
+                UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) {
             record.isDisabledByAdmin = true;
             record.enforcedAdmin = admin;
         } else {
@@ -683,7 +688,7 @@
     }
 
     public final QSTile.DetailAdapter userDetailAdapter = new QSTile.DetailAdapter() {
-        private final Intent USER_SETTINGS_INTENT = new Intent("android.settings.USER_SETTINGS");
+        private final Intent USER_SETTINGS_INTENT = new Intent(Settings.ACTION_USER_SETTINGS);
 
         @Override
         public CharSequence getTitle() {
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 bf4245b..f078b53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -18,10 +18,12 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeAnimator;
 import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -32,6 +34,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.os.Handler;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
@@ -56,6 +59,8 @@
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.NotificationOverflowContainer;
+import com.android.systemui.statusbar.NotificationSettingsIconRow;
+import com.android.systemui.statusbar.NotificationSettingsIconRow.SettingsIconRowListener;
 import com.android.systemui.statusbar.StackScrollerDecorView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -72,7 +77,8 @@
  */
 public class NotificationStackScrollLayout extends ViewGroup
         implements SwipeHelper.Callback, ExpandHelper.Callback, ScrollAdapter,
-        ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener {
+        ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener,
+        SettingsIconRowListener {
 
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "StackScroller";
@@ -207,6 +213,11 @@
      */
     private int mMaxScrollAfterExpand;
     private SwipeHelper.LongPressListener mLongPressListener;
+    private GearDisplayedListener mGearDisplayedListener;
+
+    private NotificationSettingsIconRow mCurrIconRow;
+    private View mTranslatingParentView;
+    private View mGearExposedView;
 
     /**
      * Should in this touch motion only be scrolling allowed? It's true when the scroller was
@@ -304,8 +315,7 @@
                 minHeight, maxHeight);
         mExpandHelper.setEventSource(this);
         mExpandHelper.setScrollAdapter(this);
-
-        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext());
+        mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, this, getContext());
         mSwipeHelper.setLongPressListener(mLongPressListener);
         mStackScrollAlgorithm = new StackScrollAlgorithm(context);
         initView(context);
@@ -321,6 +331,13 @@
     }
 
     @Override
+    public void onGearTouched(ExpandableNotificationRow row) {
+        if (mLongPressListener != null) {
+            mLongPressListener.onLongPress(row, 0, 0);
+        }
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, mBackgroundPaint);
         if (DEBUG) {
@@ -630,6 +647,10 @@
         mLongPressListener = listener;
     }
 
+    public void setGearDisplayedListener(GearDisplayedListener listener) {
+        mGearDisplayedListener = listener;
+    }
+
     public void setQsContainer(ViewGroup qsContainer) {
         mQsContainer = qsContainer;
     }
@@ -666,7 +687,7 @@
     }
 
     @Override
-    public void onChildSnappedBack(View animView) {
+    public void onChildSnappedBack(View animView, float targetLeft) {
         mAmbientState.onDragFinished(animView);
         if (!mDragAnimPendingChildren.contains(animView)) {
             if (mAnimationsEnabled) {
@@ -678,6 +699,13 @@
             // We start the swipe and snap back in the same frame, we don't want any animation
             mDragAnimPendingChildren.remove(animView);
         }
+
+        if (targetLeft == 0 && mCurrIconRow != null) {
+            mCurrIconRow.resetState();
+            if (mGearExposedView != null && mGearExposedView == mTranslatingParentView) {
+                mGearExposedView = null;
+            }
+        }
     }
 
     @Override
@@ -686,7 +714,7 @@
             mScrimController.setTopHeadsUpDragAmount(animView,
                     Math.min(Math.abs(swipeProgress - 1.0f), 1.0f));
         }
-        return false;
+        return true; // Don't fade out the notification
     }
 
     public void onBeginDrag(View v) {
@@ -726,8 +754,21 @@
         return mPhoneStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
     }
 
+    @Override
     public View getChildAtPosition(MotionEvent ev) {
-        return getChildAtPosition(ev.getX(), ev.getY());
+        View child = getChildAtPosition(ev.getX(), ev.getY());
+        if (child instanceof ExpandableNotificationRow) {
+            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+            ExpandableNotificationRow parent = row.getNotificationParent();
+            if (mGearExposedView != null && parent != null
+                    && parent.areChildrenExpanded() && mGearExposedView == parent) {
+                // In this case the group is expanded and showing the gear for the
+                // group, further interaction should apply to the group, not any
+                // child notifications so we use the parent of the child.
+                child = row.getNotificationParent();
+            }
+        }
+        return child;
     }
 
     public ExpandableView getClosestChildAtRawPosition(float touchX, float touchY) {
@@ -841,10 +882,6 @@
         return mScrollingEnabled;
     }
 
-    public View getChildContentView(View v) {
-        return v;
-    }
-
     public boolean canChildBeDismissed(View v) {
         return StackScrollAlgorithm.canChildBeDismissed(v);
     }
@@ -3008,6 +3045,9 @@
             disableClipOptimization();
         }
         handleDismissAllClipping();
+        if (mCurrIconRow != null & mCurrIconRow.isVisible()) {
+            mCurrIconRow.getNotificationParent().animateTranslateNotification(0 /* left target */);
+        }
     }
 
     private void handleDismissAllClipping() {
@@ -3268,6 +3308,247 @@
         public void flingTopOverscroll(float velocity, boolean open);
     }
 
+    /**
+     * A listener that is notified when the gear is shown behind a notification.
+     */
+    public interface GearDisplayedListener {
+        void onGearDisplayed(ExpandableNotificationRow row);
+    }
+
+    private class NotificationSwipeHelper extends SwipeHelper {
+        private static final int MOVE_STATE_LEFT = -1;
+        private static final int MOVE_STATE_UNDEFINED = 0;
+        private static final int MOVE_STATE_RIGHT = 1;
+
+        private static final long GEAR_SHOW_DELAY = 60;
+
+        private ArrayList<View> mTranslatingViews = new ArrayList<>();
+        private CheckForDrag mCheckForDrag;
+        private Handler mHandler;
+        private int mMoveState = MOVE_STATE_UNDEFINED;
+
+        public NotificationSwipeHelper(int swipeDirection, Callback callback, Context context) {
+            super(swipeDirection, callback, context);
+            mHandler = new Handler();
+        }
+
+        @Override
+        public void onDownUpdate(View currView) {
+            // Set the active view
+            mTranslatingParentView = currView;
+
+            // Reset check for drag gesture
+            mCheckForDrag = null;
+
+            // Slide back any notifications that might be showing a gear
+            resetExposedGearView();
+
+            if (currView instanceof ExpandableNotificationRow) {
+                // Set the listener for the current row's gear
+                mCurrIconRow = ((ExpandableNotificationRow) currView).getSettingsRow();
+                mCurrIconRow.setGearListener(NotificationStackScrollLayout.this);
+
+                // And the translating children
+                mTranslatingViews = ((ExpandableNotificationRow) currView).getContentViews();
+            }
+            mMoveState = MOVE_STATE_UNDEFINED;
+        }
+
+        @Override
+        public void onMoveUpdate(View view, float translation, float delta) {
+            final int newMoveState = (delta < 0) ? MOVE_STATE_RIGHT : MOVE_STATE_LEFT;
+            if (mMoveState != MOVE_STATE_UNDEFINED && mMoveState != newMoveState) {
+                // Changed directions, make sure we check for drag again.
+                mCheckForDrag = null;
+            }
+            mMoveState = newMoveState;
+
+            if (view instanceof ExpandableNotificationRow) {
+                ((ExpandableNotificationRow) view).setTranslationForOutline(translation);
+                if (!isPinnedHeadsUp(view)) {
+                    // Only show the gear if we're not a heads up view.
+                    checkForDrag();
+                    if (mCurrIconRow != null) {
+                        mCurrIconRow.updateSettingsIcons(translation, getSize(view));
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void dismissChild(final View view, float velocity) {
+            cancelCheckForDrag();
+            super.dismissChild(view, velocity);
+        }
+
+        @Override
+        public void snapChild(final View animView, final float targetLeft, float velocity) {
+            final float snapBackThreshold = getSpaceForGear(animView);
+            final float translation = getTranslation(animView);
+            final boolean fromLeft = translation > 0;
+            final float absTrans = Math.abs(translation);
+            final float notiThreshold = getSize(mTranslatingParentView) * 0.4f;
+
+            boolean pastGear = (fromLeft && translation >= snapBackThreshold * 0.4f
+                    && translation <= notiThreshold) ||
+                    (!fromLeft && absTrans >= snapBackThreshold * 0.4f
+                            && absTrans <= notiThreshold);
+
+            if (pastGear && !isPinnedHeadsUp(animView)) {
+                // bouncity
+                final float target = fromLeft ? snapBackThreshold : -snapBackThreshold;
+                mGearExposedView = mTranslatingParentView;
+                if (mGearDisplayedListener != null
+                        && (animView instanceof ExpandableNotificationRow)) {
+                    mGearDisplayedListener.onGearDisplayed((ExpandableNotificationRow) animView);
+                }
+                super.snapChild(animView, target, velocity);
+            } else {
+                super.snapChild(animView, 0, velocity);
+            }
+        }
+
+        @Override
+        public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
+            if (mDismissAllInProgress) {
+                // When dismissing all, we translate the entire view instead.
+                super.onTranslationUpdate(animView, value, canBeDismissed);
+                return;
+            }
+            if (animView instanceof ExpandableNotificationRow) {
+                ((ExpandableNotificationRow) animView).setTranslationForOutline(value);
+            }
+            if (mCurrIconRow != null) {
+                mCurrIconRow.updateSettingsIcons(value, getSize(animView));
+            }
+        }
+
+        @Override
+        public Animator getViewTranslationAnimator(View v, float target,
+                AnimatorUpdateListener listener) {
+            if (mDismissAllInProgress) {
+                // When dismissing all, we translate the entire view instead.
+                return super.getViewTranslationAnimator(v, target, listener);
+            }
+            ArrayList<Animator> animators = new ArrayList<Animator>();
+            for (int i = 0; i < mTranslatingViews.size(); i++) {
+                ObjectAnimator anim = createTranslationAnimation(mTranslatingViews.get(i), target);
+                animators.add(anim);
+                if (i == 0 && listener != null) {
+                    anim.addUpdateListener(listener);
+                }
+            }
+            AnimatorSet set = new AnimatorSet();
+            set.playTogether(animators);
+            return set;
+        }
+
+        @Override
+        public void setTranslation(View v, float translate) {
+            if (mDismissAllInProgress) {
+                // When dismissing all, we translate the entire view instead.
+                super.setTranslation(v, translate);
+                return;
+            }
+            // Translate the group of views
+            for (int i = 0; i < mTranslatingViews.size(); i++) {
+                if (mTranslatingViews.get(i) != null) {
+                    super.setTranslation(mTranslatingViews.get(i), translate);
+                }
+            }
+        }
+
+        @Override
+        public float getTranslation(View v) {
+            if (mDismissAllInProgress) {
+                // When dismissing all, we translate the entire view instead.
+                return super.getTranslation(v);
+            }
+            // All of the views in the list should have same translation, just use first one.
+            if (mTranslatingViews.size() > 0) {
+                return super.getTranslation(mTranslatingViews.get(0));
+            }
+            return 0;
+        }
+
+
+        /**
+         * Returns the horizontal space in pixels required to display the gear behind a
+         * notification.
+         */
+        private float getSpaceForGear(View view) {
+            if (view instanceof ExpandableNotificationRow) {
+                return ((ExpandableNotificationRow) view).getSpaceForGear();
+            }
+            return 0;
+        }
+
+        private void checkForDrag() {
+            if (mCheckForDrag == null) {
+                mCheckForDrag = new CheckForDrag();
+                mHandler.postDelayed(mCheckForDrag, GEAR_SHOW_DELAY);
+            }
+        }
+
+        private void cancelCheckForDrag() {
+            if (mCurrIconRow != null) {
+                mCurrIconRow.cancelFadeAnimator();
+            }
+            mHandler.removeCallbacks(mCheckForDrag);
+            mCheckForDrag = null;
+        }
+
+        private final class CheckForDrag implements Runnable {
+            @Override
+            public void run() {
+                final float translation = getTranslation(mTranslatingParentView);
+                final float absTransX = Math.abs(translation);
+                final float bounceBackToGearWidth = getSpaceForGear(mTranslatingParentView);
+                final float notiThreshold = getSize(mTranslatingParentView) * 0.4f;
+                if (mCurrIconRow != null && absTransX >= bounceBackToGearWidth * 0.4
+                        && absTransX < notiThreshold) {
+                    // Show icon
+                    mCurrIconRow.fadeInSettings(translation > 0 /* fromLeft */, translation,
+                            notiThreshold);
+                } else {
+                    // Allow more to be posted if this wasn't a drag.
+                    mCheckForDrag = null;
+                }
+            }
+        }
+
+        private void resetExposedGearView() {
+            if (mGearExposedView == null || mGearExposedView == mTranslatingParentView) {
+                // If no gear is showing or it's showing for this view we do nothing.
+                return;
+            }
+
+            final View prevGearExposedView = mGearExposedView;
+            mGearExposedView = null;
+
+            AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+                public void onAnimationEnd(Animator animator) {
+                    if (prevGearExposedView instanceof ExpandableNotificationRow) {
+                        ((ExpandableNotificationRow) prevGearExposedView).getSettingsRow()
+                                .resetState();
+                    }
+                }
+            };
+            AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    if (prevGearExposedView instanceof ExpandableNotificationRow) {
+                        ((ExpandableNotificationRow) prevGearExposedView)
+                                .setTranslationForOutline((float) animation.getAnimatedValue());
+                    }
+                }
+            };
+            Animator set = getViewTranslationAnimator(prevGearExposedView, 0, updateListener);
+            set.addListener(listener);
+            set.start();
+        }
+    }
+
     static class AnimationEvent {
 
         static AnimationFilter[] FILTERS = new AnimationFilter[] {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
new file mode 100644
index 0000000..8881c79
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
@@ -0,0 +1,96 @@
+/*
+ * 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.tuner;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.DropDownPreference;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.AttributeSet;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+
+import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
+
+public class BatteryPreference extends DropDownPreference implements TunerService.Tunable {
+
+    private static final String PERCENT = "percent";
+    private static final String DEFAULT = "default";
+    private static final String DISABLED = "disabled";
+
+    private final String mBattery;
+    private boolean mBatteryEnabled;
+    private boolean mHasPercentage;
+    private ArraySet<String> mBlacklist;
+    private boolean mHasSetValue;
+
+    public BatteryPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mBattery = context.getString(com.android.internal.R.string.status_bar_battery);
+        setEntryValues(new CharSequence[] {PERCENT, DEFAULT, DISABLED });
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+        mHasPercentage = Settings.System.getInt(getContext().getContentResolver(),
+                SHOW_PERCENT_SETTING, 0) != 0;
+    }
+
+    @Override
+    public void onDetached() {
+        TunerService.get(getContext()).removeTunable(this);
+        super.onDetached();
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
+            mBlacklist = StatusBarIconController.getIconBlacklist(newValue);
+            mBatteryEnabled = !mBlacklist.contains(mBattery);
+        }
+        if (!mHasSetValue) {
+            // Because of the complicated tri-state it can end up looping and setting state back to
+            // what the user didn't choose.  To avoid this, just set the state once and rely on the
+            // preference to handle updates.
+            mHasSetValue = true;
+            if (mBatteryEnabled && mHasPercentage) {
+                setValue(PERCENT);
+            } else if (mBatteryEnabled) {
+                setValue(DEFAULT);
+            } else {
+                setValue(DISABLED);
+            }
+        }
+    }
+
+    @Override
+    protected boolean persistString(String value) {
+        final boolean v = PERCENT.equals(value);
+        MetricsLogger.action(getContext(), MetricsEvent.TUNER_BATTERY_PERCENTAGE, v);
+        Settings.System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
+        if (DISABLED.equals(value)) {
+            mBlacklist.add(mBattery);
+        } else {
+            mBlacklist.remove(mBattery);
+        }
+        TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
+                TextUtils.join(",", mBlacklist));
+        return true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/CalibratePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/CalibratePreference.java
new file mode 100644
index 0000000..ff7be13
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/CalibratePreference.java
@@ -0,0 +1,25 @@
+/*
+ * 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.tuner;
+
+import android.content.Context;
+import android.support.v7.preference.DialogPreference;
+import android.util.AttributeSet;
+
+public class CalibratePreference extends DialogPreference {
+    public CalibratePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
new file mode 100644
index 0000000..ea92443
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
@@ -0,0 +1,90 @@
+/*
+ * 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.tuner;
+
+import android.content.Context;
+import android.support.v7.preference.DropDownPreference;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.AttributeSet;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.policy.Clock;
+
+public class ClockPreference extends DropDownPreference implements TunerService.Tunable {
+
+    private static final String SECONDS = "seconds";
+    private static final String DEFAULT = "default";
+    private static final String DISABLED = "disabled";
+
+    private final String mClock;
+    private boolean mClockEnabled;
+    private boolean mHasSeconds;
+    private ArraySet<String> mBlacklist;
+    private boolean mHasSetValue;
+
+    public ClockPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mClock = context.getString(com.android.internal.R.string.status_bar_clock);
+        setEntryValues(new CharSequence[] { SECONDS, DEFAULT, DISABLED });
+    }
+
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
+                Clock.CLOCK_SECONDS);
+    }
+
+    @Override
+    public void onDetached() {
+        TunerService.get(getContext()).removeTunable(this);
+        super.onDetached();
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
+            mBlacklist = StatusBarIconController.getIconBlacklist(newValue);
+            mClockEnabled = !mBlacklist.contains(mClock);
+        } else if (Clock.CLOCK_SECONDS.equals(key)) {
+            mHasSeconds = newValue != null && Integer.parseInt(newValue) != 0;
+        }
+        if (!mHasSetValue) {
+            // Because of the complicated tri-state it can end up looping and setting state back to
+            // what the user didn't choose.  To avoid this, just set the state once and rely on the
+            // preference to handle updates.
+            mHasSetValue = true;
+            if (mClockEnabled && mHasSeconds) {
+                setValue(SECONDS);
+            } else if (mClockEnabled) {
+                setValue(DEFAULT);
+            } else {
+                setValue(DISABLED);
+            }
+        }
+    }
+
+    @Override
+    protected boolean persistString(String value) {
+        TunerService.get(getContext()).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1 : 0);
+        if (DISABLED.equals(value)) {
+            mBlacklist.add(mClock);
+        } else {
+            mBlacklist.remove(mClock);
+        }
+        TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
+                TextUtils.join(",", mBlacklist));
+        return true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ColorAndAppearanceFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/ColorAndAppearanceFragment.java
new file mode 100644
index 0000000..9f11325
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ColorAndAppearanceFragment.java
@@ -0,0 +1,202 @@
+/*
+ * 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.tuner;
+
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.SeekBar;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NightModeController;
+
+public class ColorAndAppearanceFragment extends PreferenceFragment {
+
+    private static final String KEY_CALIBRATE = "calibrate";
+
+    private static final long RESET_DELAY = 10000;
+    private static final CharSequence KEY_NIGHT_MODE = "night_mode";
+
+    private NightModeController mNightModeController;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mNightModeController = new NightModeController(getContext());
+    }
+
+    @Override
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        addPreferencesFromResource(R.xml.color_and_appearance);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // TODO: Figure out better title model for Tuner, to avoid any more of this.
+        getActivity().setTitle(R.string.color_and_appearance);
+
+        Preference nightMode = findPreference(KEY_NIGHT_MODE);
+        nightMode.setSummary(mNightModeController.isEnabled()
+                ? R.string.night_mode_on : R.string.night_mode_off);
+    }
+
+    @Override
+    public void onDisplayPreferenceDialog(Preference preference) {
+        if (preference instanceof CalibratePreference) {
+            CalibrateDialog.show(this);
+        } else {
+            super.onDisplayPreferenceDialog(preference);
+        }
+    }
+
+    private void startRevertTimer() {
+        getView().postDelayed(mResetColorMatrix, RESET_DELAY);
+    }
+
+    private void onApply() {
+        mNightModeController.setCustomValues(Settings.Secure.getString(
+                getContext().getContentResolver(), Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX));
+        getView().removeCallbacks(mResetColorMatrix);
+    }
+
+    private void onRevert() {
+        getView().removeCallbacks(mResetColorMatrix);
+        mResetColorMatrix.run();
+    }
+
+    private final Runnable mResetColorMatrix = new Runnable() {
+        @Override
+        public void run() {
+            ((DialogFragment) getFragmentManager().findFragmentByTag("RevertWarning")).dismiss();
+            Settings.Secure.putString(getContext().getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
+        }
+    };
+
+    public static class CalibrateDialog extends DialogFragment implements
+            DialogInterface.OnClickListener {
+        private float[] mValues;
+        private NightModeController mNightModeController;
+
+        public static void show(ColorAndAppearanceFragment fragment) {
+            CalibrateDialog dialog = new CalibrateDialog();
+            dialog.setTargetFragment(fragment, 0);
+            dialog.show(fragment.getFragmentManager(), "Calibrate");
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNightModeController = new NightModeController(getContext());
+            String customValues = mNightModeController.getCustomValues();
+            if (customValues == null) {
+                // Generate this as a string because its the easiest way to generate a copy of the
+                // identity.
+                customValues = NightModeController.toString(NightModeController.IDENTITY_MATRIX);
+            }
+            mValues = NightModeController.toValues(customValues);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            View v = LayoutInflater.from(getContext()).inflate(R.layout.calibrate_sliders, null);
+            bindView(v.findViewById(R.id.r_group), 0);
+            bindView(v.findViewById(R.id.g_group), 5);
+            bindView(v.findViewById(R.id.b_group), 10);
+            return new AlertDialog.Builder(getContext())
+                    .setTitle(R.string.calibrate_display)
+                    .setView(v)
+                    .setPositiveButton(R.string.color_apply, this)
+                    .setNegativeButton(android.R.string.cancel, null)
+                    .create();
+        }
+
+        private void bindView(View view, final int index) {
+            SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
+            seekBar.setMax(1000);
+            seekBar.setProgress((int) (1000 * mValues[index]));
+            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+                @Override
+                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                    mValues[index] = progress / 1000f;
+                }
+
+                @Override
+                public void onStartTrackingTouch(SeekBar seekBar) {
+                }
+
+                @Override
+                public void onStopTrackingTouch(SeekBar seekBar) {
+                }
+            });
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (mValues[0] == 1 && mValues[5] == 1 && mValues[10] == 1) {
+                // Allow removal of matrix by all values set to highest.
+                mNightModeController.setCustomValues(null);
+                return;
+            }
+            ((ColorAndAppearanceFragment) getTargetFragment()).startRevertTimer();
+            Settings.Secure.putString(getContext().getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
+                    NightModeController.toString(mValues));
+            RevertWarning.show((ColorAndAppearanceFragment) getTargetFragment());
+        }
+    }
+
+    public static class RevertWarning extends DialogFragment
+            implements DialogInterface.OnClickListener {
+
+        public static void show(ColorAndAppearanceFragment fragment) {
+            RevertWarning warning = new RevertWarning();
+            warning.setTargetFragment(fragment, 0);
+            warning.show(fragment.getFragmentManager(), "RevertWarning");
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            AlertDialog alertDialog = new AlertDialog.Builder(getContext())
+                    .setTitle(R.string.color_revert_title)
+                    .setMessage(R.string.color_revert_message)
+                    .setPositiveButton(R.string.ok, this)
+                    .create();
+            alertDialog.setCanceledOnTouchOutside(true);
+            return alertDialog;
+        }
+
+        @Override
+        public void onCancel(DialogInterface dialog) {
+            super.onCancel(dialog);
+            ((ColorAndAppearanceFragment) getTargetFragment()).onRevert();
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            ((ColorAndAppearanceFragment) getTargetFragment()).onApply();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixFragment.java
deleted file mode 100644
index dfacd03..0000000
--- a/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixFragment.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/**
- * Copyright (c) 2015, 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.tuner;
-
-import android.annotation.Nullable;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.support.v14.preference.PreferenceFragment;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.DropDownPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.SeekBar;
-import android.widget.Switch;
-
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.QSTileHost;
-import com.android.systemui.statusbar.policy.DisplayController;
-
-import java.util.Objects;
-
-public class ColorMatrixFragment extends PreferenceFragment implements TunerService.Tunable {
-
-    private static final String TAG = "ColorMatrixFragment";
-
-    private static final long RESET_DELAY = 10000;
-
-    private boolean mCustomEnabled;
-    private DropDownPreference mSelectPreference;
-    private String mCurrentValue;
-    private String mCustomValues;
-    private SwitchPreference mEnableCustomPreference;
-    private MatrixPreference mCustomPreference;
-    private int mState;
-    private Switch mSwitch;
-
-    @Override
-    public void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        Context context = getContext();
-        TunerService.get(context).addTunable(this, DisplayController.COLOR_MATRIX_CUSTOM_ENABLED,
-                DisplayController.COLOR_MATRIX_CUSTOM_VALUES, DisplayController.COLOR_STATE,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        final View view = LayoutInflater.from(getContext()).inflate(
-                R.layout.color_matrix_settings, container, false);
-        ((ViewGroup) view).addView(super.onCreateView(inflater, container, savedInstanceState));
-        return view;
-    }
-
-    @Override
-    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        final Context context = getPreferenceManager().getContext();
-        setPreferenceScreen(getPreferenceManager().createPreferenceScreen(context));
-
-        mSelectPreference = new DropDownPreference(context);
-        mSelectPreference.setTitle(R.string.color_transform);
-        mSelectPreference.setSummary("%s");
-        mSelectPreference.setOnPreferenceChangeListener(
-                new Preference.OnPreferenceChangeListener() {
-            @Override
-            public boolean onPreferenceChange(Preference preference, Object newValue) {
-                if (Objects.equals(newValue, DisplayController.AUTO_STRING)) {
-                    Settings.Secure.putInt(context.getContentResolver(),
-                            DisplayController.COLOR_STATE,
-                            DisplayController.COLOR_STATE_AUTO);
-                    return true;
-                }
-                if (Objects.equals(newValue, DisplayController.NONE_STRING)) {
-                    Settings.Secure.putString(context.getContentResolver(),
-                            Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
-                    return true;
-                }
-                Settings.Secure.putInt(context.getContentResolver(),
-                        DisplayController.COLOR_STATE,
-                        DisplayController.COLOR_STATE_ENABLED);
-                final String value = (String) newValue;
-                Settings.Secure.putString(context.getContentResolver(),
-                        Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
-                        value);
-                return true;
-            }
-        });
-        getPreferenceScreen().addPreference(mSelectPreference);
-
-        mEnableCustomPreference = new SwitchPreference(context);
-        mEnableCustomPreference.setTitle(R.string.color_enable_custom);
-        mEnableCustomPreference.setOnPreferenceChangeListener(
-                new Preference.OnPreferenceChangeListener() {
-            @Override
-            public boolean onPreferenceChange(Preference preference, Object newValue) {
-                boolean enabled = (Boolean) newValue;
-                if (!enabled && Objects.equals(mCurrentValue, mCustomValues)) {
-                    Settings.Secure.putString(context.getContentResolver(),
-                            Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
-                }
-                Settings.Secure.putInt(context.getContentResolver(),
-                        DisplayController.COLOR_MATRIX_CUSTOM_ENABLED, enabled ? 1 : 0);
-                return true;
-            }
-        });
-        getPreferenceScreen().addPreference(mEnableCustomPreference);
-
-        mCustomPreference = new MatrixPreference(context);
-        getPreferenceScreen().addPreference(mCustomPreference);
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        View switchBar = view.findViewById(R.id.switch_bar);
-        mSwitch = (Switch) switchBar.findViewById(android.R.id.switch_widget);
-        mSwitch.setChecked(mState != DisplayController.COLOR_STATE_DISABLED);
-        switchBar.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                int newState = mState != DisplayController.COLOR_STATE_DISABLED
-                        ? DisplayController.COLOR_STATE_DISABLED
-                        : DisplayController.COLOR_STATE_ENABLED;
-                ContentResolver contentResolver = getContext().getContentResolver();
-                if (newState == DisplayController.COLOR_STATE_DISABLED) {
-                    String tiles = Settings.Secure.getString(contentResolver,
-                            QSTileHost.TILES_SETTING);
-                    if (tiles != null) {
-                        if (tiles.contains(",colors")) {
-                            tiles = tiles.replace(",colors", "");
-                        } else if (tiles.contains("colors,")) {
-                            tiles = tiles.replace("colors,", "");
-                        }
-                        Settings.Secure.putString(contentResolver, QSTileHost.TILES_SETTING,
-                                tiles);
-                    }
-                }
-                Settings.Secure.putInt(contentResolver,
-                        DisplayController.COLOR_STATE, newState);
-            }
-        });
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        TunerService.get(getContext()).removeTunable(this);
-    }
-
-    @Override
-    public void onTuningChanged(String key, String newValue) {
-        if (DisplayController.COLOR_MATRIX_CUSTOM_ENABLED.equals(key)) {
-            mCustomEnabled = newValue != null && Integer.parseInt(newValue) != 0;
-            mEnableCustomPreference.setChecked(mCustomEnabled);
-            mCustomPreference.setEnabled(mCustomEnabled
-                    && mState != DisplayController.COLOR_STATE_DISABLED);
-            updateSelectOptions();
-        } else if (DisplayController.COLOR_MATRIX_CUSTOM_VALUES.equals(key)) {
-            mCustomValues = newValue;
-            if (mCustomValues == null) {
-                mCustomValues = DisplayController.toString(DisplayController.IDENTITY_MATRIX);
-            }
-            mCustomPreference.setValues(mCustomValues);
-            updateSelectOptions();
-        } else if (DisplayController.COLOR_STATE.equals(key)) {
-            mState = newValue != null ? Integer.parseInt(newValue) : 0;
-            if (mSwitch != null) {
-                mSwitch.setChecked(mState != DisplayController.COLOR_STATE_DISABLED);
-            }
-            mSelectPreference.setEnabled(mState != DisplayController.COLOR_STATE_DISABLED);
-            mEnableCustomPreference.setEnabled(mState != DisplayController.COLOR_STATE_DISABLED);
-            mCustomPreference.setEnabled(mCustomEnabled
-                    && mState != DisplayController.COLOR_STATE_DISABLED);
-        } else {
-            mCurrentValue = newValue;
-            updateSelectOptions();
-        }
-    }
-
-    private void updateSelectOptions() {
-        final int N = DisplayController.CUSTOM_INDEX + (mCustomEnabled ? 1 : 0);
-        String[] values = new String[N];
-        CharSequence[] names = new CharSequence[N];
-        CharSequence[] totalNames = DisplayController.getColorTitles(getContext());
-        String[] entries = DisplayController.getColorTransforms(getContext());
-        entries[DisplayController.CUSTOM_INDEX] = mCustomValues != null ? mCustomValues : "";
-        for (int i = 0; i < N; i++) {
-            values[i] = entries[i];
-            names[i] = totalNames[i];
-        }
-        mSelectPreference.setEntries(names);
-        mSelectPreference.setEntryValues(values);
-        int index = 0;
-        if (mState == DisplayController.COLOR_STATE_AUTO) {
-            index = DisplayController.AUTO_INDEX;
-        } else if (mCustomValues != null && Objects.equals(mCurrentValue, mCustomValues)) {
-            index = DisplayController.CUSTOM_INDEX;
-        } else if (Objects.equals(mCurrentValue, entries[1])) {
-            index = 1;
-        }
-        mSelectPreference.setValueIndex(index);
-        mSelectPreference.setSummary("%s");
-        return;
-    }
-
-    private void startRevertTimer() {
-        getView().postDelayed(mResetColorMatrix, RESET_DELAY);
-    }
-
-    private void onApply() {
-        Settings.Secure.putString(getContext().getContentResolver(),
-                DisplayController.COLOR_MATRIX_CUSTOM_VALUES, mCurrentValue);
-        getView().removeCallbacks(mResetColorMatrix);
-    }
-
-    private void onRevert() {
-        getView().removeCallbacks(mResetColorMatrix);
-        mResetColorMatrix.run();
-    }
-
-    private final Runnable mResetColorMatrix = new Runnable() {
-        @Override
-        public void run() {
-            ((DialogFragment) getFragmentManager().findFragmentByTag("RevertWarning")).dismiss();
-            Settings.Secure.putString(getContext().getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, null);
-        }
-    };
-
-    private class MatrixPreference extends Preference implements View.OnClickListener {
-        private float[] mValues;
-
-        public MatrixPreference(Context context) {
-            super(context);
-            setLayoutResource(R.layout.preference_matrix);
-        }
-
-        public void setValues(String customValues) {
-            String[] strValues = customValues.split(",");
-            mValues = new float[strValues.length];
-            for (int i = 0; i < mValues.length; i++) {
-                mValues[i] = Float.parseFloat(strValues[i]);
-            }
-            notifyChanged();
-        }
-
-        @Override
-        public void onBindViewHolder(PreferenceViewHolder holder) {
-            super.onBindViewHolder(holder);
-            bindView(holder.findViewById(R.id.r_group), 0);
-            bindView(holder.findViewById(R.id.g_group), 5);
-            bindView(holder.findViewById(R.id.b_group), 10);
-            holder.findViewById(R.id.apply).setOnClickListener(this);
-        }
-
-        private void bindView(View view, final int index) {
-            SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
-            seekBar.setMax(1000);
-            seekBar.setProgress((int) (1000 * mValues[index]));
-            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-                @Override
-                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-                    mValues[index] = progress / 1000f;
-                }
-
-                @Override
-                public void onStartTrackingTouch(SeekBar seekBar) {
-                }
-
-                @Override
-                public void onStopTrackingTouch(SeekBar seekBar) {
-                }
-            });
-        }
-
-        @Override
-        public void onClick(View v) {
-            startRevertTimer();
-            Settings.Secure.putString(getContext().getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
-                    DisplayController.toString(mValues));
-            RevertWarning.show(ColorMatrixFragment.this);
-        }
-
-    }
-
-    public static class RevertWarning extends DialogFragment
-            implements DialogInterface.OnClickListener {
-
-        public static void show(ColorMatrixFragment fragment) {
-            RevertWarning warning = new RevertWarning();
-            warning.setTargetFragment(fragment, 0);
-            warning.show(fragment.getFragmentManager(), "RevertWarning");
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            AlertDialog alertDialog = new AlertDialog.Builder(getContext())
-                    .setTitle(R.string.color_revert_title)
-                    .setMessage(R.string.color_revert_message)
-                    .setPositiveButton(R.string.ok, this)
-                    .create();
-            alertDialog.setCanceledOnTouchOutside(true);
-            return alertDialog;
-        }
-
-        @Override
-        public void onCancel(DialogInterface dialog) {
-            super.onCancel(dialog);
-            ((ColorMatrixFragment) getTargetFragment()).onRevert();
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            ((ColorMatrixFragment) getTargetFragment()).onApply();
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixTile.java b/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixTile.java
deleted file mode 100644
index d8cf2e2..0000000
--- a/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixTile.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Copyright (c) 2015, 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.tuner;
-
-import android.app.ActivityManager;
-import android.provider.Settings;
-
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-import com.android.systemui.qs.QSTile;
-import com.android.systemui.statusbar.policy.DisplayController;
-
-import java.util.Objects;
-
-
-public class ColorMatrixTile extends QSTile<QSTile.State> implements DisplayController.Listener {
-
-    public static final String COLOR_MATRIX_SPEC = "colors";
-
-    private final DisplayController mDisplayController;
-
-    private int mIndex;
-    private String mCurrentValue;
-
-    private boolean mCustomEnabled;
-    private String[] mValues;
-    private CharSequence[] mValueTitles;
-
-    public ColorMatrixTile(Host host) {
-        super(host);
-        mDisplayController = host.getDisplayController();
-    }
-
-    @Override
-    public void setListening(boolean listening) {
-        if (listening) {
-            mValues = DisplayController.getColorTransforms(mContext);
-            mValueTitles = DisplayController.getColorTitles(mContext);
-            mDisplayController.addListener(this);
-        } else {
-            mDisplayController.removeListener(this);
-        }
-    }
-
-    @Override
-    public State newTileState() {
-        return new State();
-    }
-
-    @Override
-    protected void handleClick() {
-        mIndex++;
-        if (mIndex == DisplayController.AUTO_INDEX) {
-            mDisplayController.setAuto(true);
-        } else {
-            mDisplayController.setAuto(false);
-            if (!mDisplayController.isCustomEnabled()
-                    && (mIndex == DisplayController.CUSTOM_INDEX)) {
-                mIndex++;
-            }
-            if (mIndex == mValues.length - 1) {
-                mIndex = 0;
-            }
-            Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, mValues[mIndex],
-                    ActivityManager.getCurrentUser());
-        }
-        refreshState();
-    }
-
-    @Override
-    protected void handleUpdateState(State state, Object arg) {
-        if (mDisplayController.isAuto()) {
-            mIndex = DisplayController.AUTO_INDEX;
-        } else if (mDisplayController.isCustomSet()) {
-            mIndex = DisplayController.CUSTOM_INDEX;
-        } else {
-            mIndex = Objects.equals(mDisplayController.getCurrentMatrix(), mValues[1]) ? 1 : 0;
-        }
-        state.icon = ResourceIcon.get(R.drawable.ic_colorize);
-        state.label = mValueTitles[mIndex];
-        state.contentDescription = mValueTitles[mIndex];
-    }
-
-    @Override
-    public void onCurrentMatrixChanged() {
-        refreshState();
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.QS_COLOR_MATRIX;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NightModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/NightModeFragment.java
new file mode 100644
index 0000000..e9650ea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NightModeFragment.java
@@ -0,0 +1,195 @@
+/**
+ * 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.tuner;
+
+import android.annotation.Nullable;
+import android.app.UiModeManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.DropDownPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Switch;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QSTileHost;
+import com.android.systemui.statusbar.policy.NightModeController;
+import com.android.systemui.statusbar.policy.NightModeController.Listener;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class NightModeFragment extends PreferenceFragment implements Tunable,
+        Listener, OnPreferenceChangeListener {
+
+    private static final String TAG = "NightModeFragment";
+
+    public static final String EXTRA_SHOW_NIGHT_MODE = "show_night_mode";
+
+    private static final CharSequence KEY_AUTO = "auto";
+    private static final CharSequence KEY_DARK_THEME = "dark_theme";
+    private static final CharSequence KEY_ADJUST_TINT = "adjust_tint";
+    private static final CharSequence KEY_ADJUST_BRIGHTNESS = "adjust_brightness";
+
+    private Switch mSwitch;
+
+    private NightModeController mNightModeController;
+    private SwitchPreference mAutoSwitch;
+    private SwitchPreference mDarkTheme;
+    private SwitchPreference mAdjustTint;
+    private SwitchPreference mAdjustBrightness;
+    private UiModeManager mUiModeManager;
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mNightModeController = new NightModeController(getContext());
+        mUiModeManager = getContext().getSystemService(UiModeManager.class);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        final View view = LayoutInflater.from(getContext()).inflate(
+                R.layout.night_mode_settings, container, false);
+        ((ViewGroup) view).addView(super.onCreateView(inflater, container, savedInstanceState));
+        return view;
+    }
+
+    @Override
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        final Context context = getPreferenceManager().getContext();
+
+        addPreferencesFromResource(R.xml.night_mode);
+        mAutoSwitch = (SwitchPreference) findPreference(KEY_AUTO);
+        mAutoSwitch.setOnPreferenceChangeListener(this);
+        mDarkTheme = (SwitchPreference) findPreference(KEY_DARK_THEME);
+        mDarkTheme.setOnPreferenceChangeListener(this);
+        mAdjustTint = (SwitchPreference) findPreference(KEY_ADJUST_TINT);
+        mAdjustTint.setOnPreferenceChangeListener(this);
+        mAdjustBrightness = (SwitchPreference) findPreference(KEY_ADJUST_BRIGHTNESS);
+        mAdjustBrightness.setOnPreferenceChangeListener(this);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        View switchBar = view.findViewById(R.id.switch_bar);
+        mSwitch = (Switch) switchBar.findViewById(android.R.id.switch_widget);
+        mSwitch.setChecked(mNightModeController.isEnabled());
+        switchBar.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                boolean newState = !mNightModeController.isEnabled();
+                mNightModeController.setNightMode(newState);
+                mSwitch.setChecked(newState);
+            }
+        });
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mNightModeController.addListener(this);
+        TunerService.get(getContext()).addTunable(this, Secure.BRIGHTNESS_USE_TWILIGHT,
+                NightModeController.NIGHT_MODE_ADJUST_TINT);
+        mDarkTheme.setChecked(mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_AUTO);
+        calculateDisabled();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mNightModeController.removeListener(this);
+        TunerService.get(getContext()).removeTunable(this);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (mAutoSwitch == preference) {
+            mNightModeController.setAuto((Boolean) newValue);
+        } else if (mDarkTheme == preference) {
+            mUiModeManager.setNightMode(((Boolean) newValue) ? UiModeManager.MODE_NIGHT_AUTO
+                    : UiModeManager.MODE_NIGHT_NO);
+            postCalculateDisabled();
+        } else if (mAdjustTint == preference) {
+            mNightModeController.setAdjustTint((Boolean) newValue);
+            postCalculateDisabled();
+        } else if (mAdjustBrightness == preference) {
+            TunerService.get(getContext()).setValue(Secure.BRIGHTNESS_USE_TWILIGHT,
+                    ((Boolean) newValue) ? 1 : 0);
+            postCalculateDisabled();
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    private void postCalculateDisabled() {
+        // Post this because its the easiest way to wait for all state to be calculated.
+        getView().post(new Runnable() {
+            @Override
+            public void run() {
+                calculateDisabled();
+            }
+        });
+    }
+
+    private void calculateDisabled() {
+        int enabledCount = (mDarkTheme.isChecked() ? 1 : 0)
+                + (mAdjustTint.isChecked() ? 1 : 0)
+                + (mAdjustBrightness.isChecked() ? 1 : 0);
+        if (enabledCount == 1) {
+            if (mDarkTheme.isChecked()) {
+                mDarkTheme.setEnabled(false);
+            } else if (mAdjustTint.isChecked()) {
+                mAdjustTint.setEnabled(false);
+            } else {
+                mAdjustBrightness.setEnabled(false);
+            }
+        } else {
+            mDarkTheme.setEnabled(true);
+            mAdjustTint.setEnabled(true);
+            mAdjustBrightness.setEnabled(true);
+        }
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (Secure.BRIGHTNESS_USE_TWILIGHT.equals(key)) {
+            mAdjustBrightness.setChecked(newValue != null && Integer.parseInt(newValue) != 0);
+        } else if (NightModeController.NIGHT_MODE_ADJUST_TINT.equals(key)) {
+            // Default on.
+            mAdjustTint.setChecked(newValue == null || Integer.parseInt(newValue) != 0);
+        }
+    }
+
+    @Override
+    public void onNightModeChanged() {
+        mSwitch.setChecked(mNightModeController.isEnabled());
+    }
+
+    @Override
+    public void onTwilightAutoChanged() {
+        mAutoSwitch.setChecked(mNightModeController.isAuto());
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
new file mode 100644
index 0000000..61135bd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
@@ -0,0 +1,99 @@
+/**
+ * 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.tuner;
+
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.provider.Settings;
+
+import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.policy.NightModeController;
+
+import java.util.Objects;
+
+
+public class NightModeTile extends QSTile<QSTile.State> implements NightModeController.Listener {
+
+    public static final String NIGHT_MODE_SPEC = "night";
+
+    private final NightModeController mNightModeController;
+
+    private int mIndex;
+    private String mCurrentValue;
+
+    private boolean mCustomEnabled;
+    private String[] mValues;
+    private CharSequence[] mValueTitles;
+
+    public NightModeTile(Host host) {
+        super(host);
+        mNightModeController = host.getNightModeController();
+    }
+
+    @Override
+    public void setListening(boolean listening) {
+        if (listening) {
+            mNightModeController.addListener(this);
+            refreshState();
+        } else {
+            mNightModeController.removeListener(this);
+        }
+    }
+
+    @Override
+    public State newTileState() {
+        return new State();
+    }
+
+    @Override
+    public Intent getLongClickIntent() {
+        return new Intent(mContext, TunerActivity.class)
+                .putExtra(NightModeFragment.EXTRA_SHOW_NIGHT_MODE, true);
+    }
+
+    @Override
+    protected void handleClick() {
+        mNightModeController.setNightMode(!mNightModeController.isEnabled());
+        refreshState();
+    }
+
+    @Override
+    protected void handleUpdateState(State state, Object arg) {
+        // TODO: Right now this is just a dropper, needs an actual night icon.
+        boolean enabled = mNightModeController.isEnabled();
+        state.icon = ResourceIcon.get(enabled ? R.drawable.ic_night_mode
+                : R.drawable.ic_night_mode_disabled);
+        state.label = mContext.getString(R.string.night_mode);
+        state.contentDescription = mContext.getString(R.string.night_mode);
+    }
+
+    @Override
+    public void onNightModeChanged() {
+        refreshState();
+    }
+
+    @Override
+    public void onTwilightAutoChanged() {
+        // Don't care.
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsEvent.QS_COLOR_MATRIX;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 4225b48..def597d 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -36,7 +36,10 @@
         super.onCreate(savedInstanceState);
 
         if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) {
-            getFragmentManager().beginTransaction().replace(R.id.content_frame, new TunerFragment(),
+            boolean showNightMode = getIntent().getBooleanExtra(
+                    NightModeFragment.EXTRA_SHOW_NIGHT_MODE, false);
+            getFragmentManager().beginTransaction().replace(R.id.content_frame,
+                    showNightMode ? new NightModeFragment() : new TunerFragment(),
                     TAG_TUNER).commit();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 9df5368..70f2fdc 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -37,8 +37,6 @@
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 
-import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
-
 public class TunerFragment extends PreferenceFragment {
 
     private static final String TAG = "TunerFragment";
@@ -51,10 +49,6 @@
 
     private static final int MENU_REMOVE = Menu.FIRST + 1;
 
-    private final SettingObserver mSettingObserver = new SettingObserver();
-
-    private SwitchPreference mBatteryPct;
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -72,7 +66,6 @@
     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
         addPreferencesFromResource(R.xml.tuner_prefs);
 
-        mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT);
         if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING,
                 0) == 0) {
             if (getFragmentManager().findFragmentByTag(WARNING_TAG) == null) {
@@ -85,9 +78,6 @@
     public void onResume() {
         super.onResume();
         getActivity().setTitle(R.string.system_ui_tuner);
-        updateBatteryPct();
-        getContext().getContentResolver().registerContentObserver(
-                System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
 
         MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, true);
     }
@@ -95,7 +85,6 @@
     @Override
     public void onPause() {
         super.onPause();
-        getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
 
         MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, false);
     }
@@ -123,35 +112,6 @@
         return super.onOptionsItemSelected(item);
     }
 
-    private void updateBatteryPct() {
-        mBatteryPct.setOnPreferenceChangeListener(null);
-        mBatteryPct.setChecked(System.getInt(getContext().getContentResolver(),
-                SHOW_PERCENT_SETTING, 0) != 0);
-        mBatteryPct.setOnPreferenceChangeListener(mBatteryPctChange);
-    }
-
-    private final class SettingObserver extends ContentObserver {
-        public SettingObserver() {
-            super(new Handler());
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri, int userId) {
-            super.onChange(selfChange, uri, userId);
-            updateBatteryPct();
-        }
-    }
-
-    private final OnPreferenceChangeListener mBatteryPctChange = new OnPreferenceChangeListener() {
-        @Override
-        public boolean onPreferenceChange(Preference preference, Object newValue) {
-            final boolean v = (Boolean) newValue;
-            MetricsLogger.action(getContext(), MetricsEvent.TUNER_BATTERY_PERCENTAGE, v);
-            System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
-            return true;
-        }
-    };
-
     public static class TunerWarningFragment extends DialogFragment {
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
index 7ad752e..b738136 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
@@ -23,7 +23,7 @@
     @Override
     public void onAttached() {
         super.onAttached();
-        TunerService.get(getContext()).addTunable(this, getKey());
+        TunerService.get(getContext()).addTunable(this, getKey().split(","));
     }
 
     @Override
@@ -39,7 +39,9 @@
 
     @Override
     protected boolean persistBoolean(boolean value) {
-        Settings.Secure.putString(getContext().getContentResolver(), getKey(), value ? "1" : "0");
+        for (String key : getKey().split(",")) {
+            Settings.Secure.putString(getContext().getContentResolver(), key, value ? "1" : "0");
+        }
         return true;
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 4be6833..388c8b7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2162,8 +2162,13 @@
                 mIntent = new Intent().setComponent(mComponentName);
                 mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                         com.android.internal.R.string.accessibility_binding_label);
-                mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
-                        mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
+                final long idendtity = Binder.clearCallingIdentity();
+                try {
+                    mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+                            mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
+                } finally {
+                    Binder.restoreCallingIdentity(idendtity);
+                }
             }
             setDynamicallyConfigurableProperties(accessibilityServiceInfo);
         }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 4646f3c..2b52799 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -159,7 +159,7 @@
                 reloadWidgetsMaskedStateForUser(userId);
             } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) {
                 synchronized (mLock) {
-                    reloadWidgetQuietModeMaskedStateLocked(userId);
+                    reloadWidgetProfileUnavailableMaskedStateLocked(userId);
                 }
             } else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) {
                 String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
@@ -432,7 +432,7 @@
 
     /**
      * Reload all widgets' masked state for the given user and its associated profiles, including
-     * due to quiet mode and package suspension.
+     * due to user not being available and package suspension.
      */
     private void reloadWidgetsMaskedStateForUser(int userId) {
         if (!mUserManager.isUserUnlocked(userId)) return;
@@ -442,7 +442,7 @@
             if (profiles != null) {
                 for (int i = 0; i < profiles.size(); i++) {
                     UserInfo user  = profiles.get(i);
-                    reloadWidgetQuietModeMaskedStateLocked(user.id);
+                    reloadWidgetProfileUnavailableMaskedStateLocked(user.id);
                     reloadWidgetPackageSuspensionMaskedStateLocked(user.id);
                 }
             }
@@ -450,17 +450,18 @@
     }
 
     /**
-     * Mask/unmask widgets in the given profile, depending on the quiet state of the profile.
+     * Mask/unmask widgets in the given profile, depending on the quiet state
+     * or locked state of the profile.
      */
-    private void reloadWidgetQuietModeMaskedStateLocked(int profileId) {
-        if (!mUserManager.isUserUnlocked(profileId)) return;
+    private void reloadWidgetProfileUnavailableMaskedStateLocked(int profileId) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            UserInfo user  = mUserManager.getUserInfo(profileId);
-            if (!user.isManagedProfile()) {
+            if (!isProfileWithUnlockedParent(profileId)) {
                 return;
             }
-            boolean shouldMask = user.isQuietModeEnabled();
+            UserInfo user  = mUserManager.getUserInfo(profileId);
+            boolean shouldMask = user.isQuietModeEnabled() ||
+                    !mUserManager.isUserUnlocked(user.getUserHandle());
             final int N = mProviders.size();
             for (int i = 0; i < N; i++) {
                 Provider provider = mProviders.get(i);
@@ -468,7 +469,7 @@
                 if (providerUserId != profileId) {
                     continue;
                 }
-                if (provider.setMaskedByQuietProfileLocked(shouldMask)) {
+                if (provider.setMaskedByProfileUnavailabledLocked(shouldMask)) {
                     if (provider.isMaskedLocked()) {
                         maskWidgetsViewsLocked(provider);
                     } else {
@@ -537,8 +538,8 @@
         }
     }
 
-    private void maskWidgetsViewsLocked(Provider provider) {
-        Bitmap iconBitmap = null;
+    private Bitmap createMaskedWidgetBitmap(Provider provider) {
+        final long identity = Binder.clearCallingIdentity();
         try {
             // Load the unbadged application icon and pass it to the widget to appear on
             // the masked view.
@@ -548,11 +549,20 @@
             PackageManager pm = userContext.getPackageManager();
             Drawable icon = pm.getApplicationInfo(providerPackage, 0).loadUnbadgedIcon(pm);
             // Create a bitmap of the icon which is what the widget's remoteview requires.
-            iconBitmap = mIconUtilities.createIconBitmap(icon);
+            return mIconUtilities.createIconBitmap(icon);
         } catch (NameNotFoundException e) {
             Slog.e(TAG, "Fail to get application icon", e);
             // Provider package removed, no need to mask its views as its state will be
             // purged very soon.
+            return null;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void maskWidgetsViewsLocked(Provider provider) {
+        Bitmap iconBitmap = createMaskedWidgetBitmap(provider);
+        if (iconBitmap == null) {
             return;
         }
 
@@ -2320,7 +2330,7 @@
                 final PackageManager pm = mContext.getPackageManager();
                 final int userId = UserHandle.getUserId(providerId.uid);
                 final ApplicationInfo app = pm.getApplicationInfoAsUser(activityInfo.packageName,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
+                        0, userId);
                 resources = pm.getResourcesForApplication(app);
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -2423,9 +2433,16 @@
             int flags = PackageManager.GET_META_DATA;
 
             // We really need packages to be around and parsed to know if they
-            // provide widgets, and we only load widgets after user is unlocked.
+            // provide widgets.
             flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
 
+            // Widget hosts that are non-crypto aware may be hosting widgets
+            // from a profile that is still locked, so let them see those
+            // widgets.
+            if (isProfileWithUnlockedParent(userId)) {
+                flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
+            }
+
             // Widgets referencing shared libraries need to have their
             // dependencies loaded.
             flags |= PackageManager.GET_SHARED_LIBRARY_FILES;
@@ -2443,6 +2460,7 @@
     private void onUserUnlocked(int userId) {
         synchronized (mLock) {
             ensureGroupStateLoadedLocked(userId);
+            reloadWidgetsMaskedStateForUser(userId);
 
             final int N = mProviders.size();
             for (int i = 0; i < N; i++) {
@@ -2580,6 +2598,17 @@
             mWidgetPackages.put(userId, packages = new ArraySet<String>());
         }
         packages.add(widget.provider.info.provider.getPackageName());
+
+        // If we are adding a widget it might be for a provider that
+        // is currently masked, if so mask the widget.
+        if (widget.provider.isMaskedLocked()) {
+            Bitmap bitmap = createMaskedWidgetBitmap(widget.provider);
+            if (bitmap != null) {
+                widget.replaceWithMaskedViewsLocked(mContext, bitmap);
+            }
+        } else {
+            widget.clearMaskedViewsLocked();
+        }
     }
 
     /**
@@ -3277,6 +3306,18 @@
         }
     }
 
+    private boolean isProfileWithUnlockedParent(int userId) {
+        UserInfo userInfo = mUserManager.getUserInfo(userId);
+        if (userInfo != null && userInfo.isManagedProfile()) {
+            UserInfo parentInfo = mUserManager.getProfileParent(userId);
+            if (parentInfo != null
+                    && mUserManager.isUserUnlocked(parentInfo.getUserHandle())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private final class CallbackHandler extends Handler {
         public static final int MSG_NOTIFY_UPDATE_APP_WIDGET = 1;
         public static final int MSG_NOTIFY_PROVIDER_CHANGED = 2;
@@ -3554,7 +3595,7 @@
         PendingIntent broadcast;
         boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
 
-        boolean maskedByQuietProfile;
+        boolean maskedByProfileUnavailable;
         boolean maskedBySuspendedPackage;
 
         int tag = TAG_UNDEFINED; // for use while saving state (the index)
@@ -3587,9 +3628,9 @@
         }
 
         // returns true if the provider's masked state is changed as a result
-        public boolean setMaskedByQuietProfileLocked(boolean masked) {
+        public boolean setMaskedByProfileUnavailabledLocked(boolean masked) {
             boolean oldMaskedState = isMaskedLocked();
-            maskedByQuietProfile = masked;
+            maskedByProfileUnavailable = masked;
             return isMaskedLocked() != oldMaskedState;
         }
 
@@ -3601,7 +3642,7 @@
         }
 
         public boolean isMaskedLocked() {
-            return maskedByQuietProfile || maskedBySuspendedPackage;
+            return maskedByProfileUnavailable || maskedBySuspendedPackage;
         }
     }
 
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 91f58c56..32f2d59 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -31,6 +31,7 @@
 import java.util.List;
 import java.util.Map;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
@@ -67,6 +68,7 @@
 import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 
 import libcore.util.EmptyArray;
@@ -103,9 +105,10 @@
         }
     };
 
-    final SparseArray<UidState> mUidStates = new SparseArray<>();
+    private final SparseArray<UidState> mUidStates = new SparseArray<>();
 
-    private final SparseArray<boolean[]> mOpRestrictions = new SparseArray<boolean[]>();
+    /** These are app op restrictions imposed per user from various parties */
+    private final ArrayMap<IBinder, SparseArray<boolean[]>> mOpUserRestrictions = new ArrayMap<>();
 
     private static final class UidState {
         public final int uid;
@@ -1263,17 +1266,21 @@
 
     private boolean isOpRestricted(int uid, int code, String packageName) {
         int userHandle = UserHandle.getUserId(uid);
-        boolean[] opRestrictions = mOpRestrictions.get(userHandle);
-        if ((opRestrictions != null) && opRestrictions[code]) {
-            if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
-                synchronized (this) {
-                    Ops ops = getOpsLocked(uid, packageName, true);
-                    if ((ops != null) && ops.isPrivileged) {
-                        return false;
+        final int restrictionSetCount = mOpUserRestrictions.size();
+        for (int i = 0; i < restrictionSetCount; i++) {
+            SparseArray<boolean[]> perUserRestrictions = mOpUserRestrictions.valueAt(i);
+            boolean[] opRestrictions = perUserRestrictions.get(userHandle);
+            if (opRestrictions != null && opRestrictions[code]) {
+                if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
+                    synchronized (this) {
+                        Ops ops = getOpsLocked(uid, packageName, true);
+                        if ((ops != null) && ops.isPrivileged) {
+                            return false;
+                        }
                     }
                 }
+                return true;
             }
-            return true;
         }
         return false;
     }
@@ -2049,27 +2056,123 @@
     }
 
     @Override
-    public void setUserRestrictions(Bundle restrictions, int userHandle) throws RemoteException {
+    public void setUserRestrictions(Bundle restrictions, IBinder token, int userHandle) {
         checkSystemUid("setUserRestrictions");
-        boolean[] opRestrictions = mOpRestrictions.get(userHandle);
-        if (opRestrictions == null) {
-            opRestrictions = new boolean[AppOpsManager._NUM_OP];
-            mOpRestrictions.put(userHandle, opRestrictions);
-        }
+        Preconditions.checkNotNull(token);
+        final boolean[] opRestrictions = getOrCreateUserRestrictionsForToken(token, userHandle);
         for (int i = 0; i < opRestrictions.length; ++i) {
             String restriction = AppOpsManager.opToRestriction(i);
-            if (restriction != null) {
-                opRestrictions[i] = restrictions.getBoolean(restriction, false);
-            } else {
-                opRestrictions[i] = false;
+            final boolean restricted = restriction != null
+                    && restrictions.getBoolean(restriction, false);
+            setUserRestrictionNoCheck(i, restricted, token, userHandle);
+        }
+    }
+
+    @Override
+    public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle) {
+        if (Binder.getCallingPid() != Process.myPid()) {
+            mContext.enforcePermission(Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS,
+                    Binder.getCallingPid(), Binder.getCallingUid(), null);
+        }
+        if (userHandle != UserHandle.getCallingUserId()) {
+            if (mContext.checkCallingOrSelfPermission(Manifest.permission
+                    .INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED
+                && mContext.checkCallingOrSelfPermission(Manifest.permission
+                    .INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Need INTERACT_ACROSS_USERS_FULL or"
+                        + " INTERACT_ACROSS_USERS to interact cross user ");
             }
         }
+        verifyIncomingOp(code);
+        Preconditions.checkNotNull(token);
+        setUserRestrictionNoCheck(code, restricted, token, userHandle);
+    }
+
+    private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token,
+            int userHandle) {
+        final boolean[] opRestrictions = getOrCreateUserRestrictionsForToken(token, userHandle);
+        if (opRestrictions[code] == restricted) {
+            return;
+        }
+        opRestrictions[code] = restricted;
+        if (!restricted) {
+            pruneUserRestrictionsForToken(token, userHandle);
+        }
+
+        final ArrayList<Callback> clonedCallbacks;
+        synchronized (this) {
+            ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
+            if (callbacks == null) {
+                return;
+            }
+            clonedCallbacks = new ArrayList<>(callbacks);
+        }
+
+        // There are components watching for mode changes such as window manager
+        // and location manager which are in our process. The callbacks in these
+        // components may require permissions our remote caller does not have.
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final int callbackCount = clonedCallbacks.size();
+            for (int i = 0; i < callbackCount; i++) {
+                Callback callback = clonedCallbacks.get(i);
+                try {
+                    callback.mCallback.opChanged(code, -1, null);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Error dispatching op op change", e);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     @Override
     public void removeUser(int userHandle) throws RemoteException {
         checkSystemUid("removeUser");
-        mOpRestrictions.remove(userHandle);
+        final int tokenCount = mOpUserRestrictions.size();
+        for (int i = tokenCount - 1; i >= 0; i--) {
+            SparseArray<boolean[]> opRestrictions = mOpUserRestrictions.valueAt(i);
+            if (opRestrictions != null) {
+                opRestrictions.remove(userHandle);
+                if (opRestrictions.size() <= 0) {
+                    mOpUserRestrictions.removeAt(i);
+                }
+            }
+        }
+    }
+
+
+    private void pruneUserRestrictionsForToken(IBinder token, int userHandle) {
+        SparseArray<boolean[]> perTokenRestrictions = mOpUserRestrictions.get(token);
+        if (perTokenRestrictions != null) {
+            final boolean[] opRestrictions = perTokenRestrictions.get(userHandle);
+            if (opRestrictions != null) {
+                for (boolean restriction : opRestrictions) {
+                    if (restriction) {
+                        return;
+                    }
+                }
+                perTokenRestrictions.remove(userHandle);
+                if (perTokenRestrictions.size() <= 0) {
+                    mOpUserRestrictions.remove(token);
+                }
+            }
+        }
+    }
+
+    private boolean[] getOrCreateUserRestrictionsForToken(IBinder token, int userHandle) {
+        SparseArray<boolean[]> perTokenRestrictions = mOpUserRestrictions.get(token);
+        if (perTokenRestrictions == null) {
+            perTokenRestrictions = new SparseArray<>();
+            mOpUserRestrictions.put(token, perTokenRestrictions);
+        }
+        boolean[] opRestrictions = perTokenRestrictions.get(userHandle);
+        if (opRestrictions == null) {
+            opRestrictions = new boolean[AppOpsManager._NUM_OP];
+            perTokenRestrictions.put(userHandle, opRestrictions);
+        }
+        return opRestrictions;
     }
 
     private void checkSystemUid(String function) {
diff --git a/services/core/java/com/android/server/HardwarePropertiesManagerService.java b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
new file mode 100644
index 0000000..cc21e99
--- /dev/null
+++ b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
@@ -0,0 +1,99 @@
+/*
+ * 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.server;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.CpuUsageInfo;
+import android.os.IHardwarePropertiesManager;
+
+import java.util.Arrays;
+
+/**
+ * Service for {@link HardwarePropertiesManager}
+ */
+public class HardwarePropertiesManagerService extends IHardwarePropertiesManager.Stub {
+
+    private static native void nativeInit();
+
+    private static native float[] nativeGetFanSpeeds();
+    private static native float[] nativeGetDeviceTemperatures(int type);
+    private static native CpuUsageInfo[] nativeGetCpuUsages();
+
+    private final Context mContext;
+    private final Object mLock = new Object();
+
+    public HardwarePropertiesManagerService(Context context) {
+        mContext = context;
+        synchronized (mLock) {
+            nativeInit();
+        }
+    }
+
+    @Override
+    public float[] getDeviceTemperatures(String callingPackage, int type) throws SecurityException {
+        enforceHardwarePropertiesRetrievalAllowed(callingPackage);
+        synchronized (mLock) {
+            return nativeGetDeviceTemperatures(type);
+        }
+    }
+
+    @Override
+    public CpuUsageInfo[] getCpuUsages(String callingPackage) throws SecurityException {
+        enforceHardwarePropertiesRetrievalAllowed(callingPackage);
+        synchronized (mLock) {
+            return nativeGetCpuUsages();
+        }
+    }
+
+    @Override
+    public float[] getFanSpeeds(String callingPackage) throws SecurityException {
+        enforceHardwarePropertiesRetrievalAllowed(callingPackage);
+        synchronized (mLock) {
+            return nativeGetFanSpeeds();
+        }
+    }
+
+    /**
+     * Throws SecurityException if the calling package is not allowed to retrieve information
+     * provided by the service.
+     *
+     * @param callingPackage The calling package name.
+     *
+     * @throws SecurityException if a non profile or device owner tries to retrieve information
+     * provided by the service.
+     */
+    private void enforceHardwarePropertiesRetrievalAllowed(String callingPackage)
+            throws SecurityException {
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            final int uid = pm.getPackageUid(callingPackage, 0);
+            if (Binder.getCallingUid() != uid) {
+                throw new SecurityException("The caller has faked the package name.");
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new SecurityException("The caller has faked the package name.");
+        }
+
+        final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+        if (!dpm.isDeviceOwnerApp(callingPackage) && !dpm.isProfileOwnerApp(callingPackage)) {
+            throw new SecurityException("The caller is not a device or profile owner.");
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 5f6fddf..d1de7e5 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -189,6 +189,7 @@
     private InputMethodFileManager mFileManager;
     private final HardKeyboardListener mHardKeyboardListener;
     private final AppOpsManager mAppOpsManager;
+    private final UserManager mUserManager;
 
     final InputBindResult mNoBinding = new InputBindResult(null, null, null, -1, -1);
 
@@ -780,6 +781,27 @@
                 mService.systemRunning(statusBarService);
             }
         }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mService.onUnlockUser(userHandle);
+        }
+    }
+
+    public void onUnlockUser(int userId) {
+        synchronized(mMethodMap) {
+            final int currentUserId = mSettings.getCurrentUserId();
+            if (DEBUG) {
+                Slog.d(TAG, "onUnlockUser: userId=" + userId + " curUserId=" + currentUserId);
+            }
+            if (userId != currentUserId) {
+                return;
+            }
+            mSettings.switchCurrentUser(currentUserId, !mSystemReady);
+            // We need to rebuild IMEs.
+            buildInputMethodListLocked(false /* resetDefaultEnabledIme */);
+            updateInputMethodsFromSettingsLocked(true /* enabledChanged */);
+        }
     }
 
     public InputMethodManagerService(Context context) {
@@ -799,6 +821,7 @@
             }
         }, true /*asyncHandler*/);
         mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+        mUserManager = mContext.getSystemService(UserManager.class);
         mHardKeyboardListener = new HardKeyboardListener();
         mHasFeature = context.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_INPUT_METHODS);
@@ -972,8 +995,10 @@
         // ContentObserver should be registered again when the user is changed
         mSettingsObserver.registerContentObserverLocked(newUserId);
 
-        // If the system is not ready, then we use copy-on-write settings.
-        final boolean useCopyOnWriteSettings = !mSystemReady;
+        // If the system is not ready or the device is not yed unlocked by the user, then we use
+        // copy-on-write settings.
+        final boolean useCopyOnWriteSettings =
+                !mSystemReady || !mUserManager.isUserUnlocked(newUserId);
         mSettings.switchCurrentUser(newUserId, useCopyOnWriteSettings);
         updateCurrentProfileIds();
         // InputMethodFileManager should be reset when the user is changed
@@ -1002,8 +1027,7 @@
     }
 
     void updateCurrentProfileIds() {
-        List<UserInfo> profiles = mContext.getSystemService(UserManager.class)
-                .getProfiles(mSettings.getCurrentUserId());
+        List<UserInfo> profiles = mUserManager.getProfiles(mSettings.getCurrentUserId());
         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
         for (int i = 0; i < currentProfileIds.length; i++) {
             currentProfileIds[i] = profiles.get(i).id;
@@ -1034,7 +1058,8 @@
             if (!mSystemReady) {
                 mSystemReady = true;
                 final int currentUserId = mSettings.getCurrentUserId();
-                mSettings.switchCurrentUser(currentUserId, false /* copyOnWrite */);
+                mSettings.switchCurrentUser(currentUserId,
+                        !mUserManager.isUserUnlocked(currentUserId));
                 mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
                 mNotificationManager = mContext.getSystemService(NotificationManager.class);
                 mStatusBar = statusBar;
@@ -2918,6 +2943,9 @@
         // Use for queryIntentServicesAsUser
         final PackageManager pm = mContext.getPackageManager();
 
+        // Note: We do not specify PackageManager.MATCH_ENCRYPTION_* flags here because the default
+        // behavior of PackageManager is exactly what we want.  It by default picks up appropriate
+        // services depending on the unlock state for the specified user.
         final List<ResolveInfo> services = pm.queryIntentServicesAsUser(
                 new Intent(InputMethod.SERVICE_INTERFACE),
                 PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 14ddc36..9884a70 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -214,7 +214,7 @@
     private int mCurrentUserId = UserHandle.USER_SYSTEM;
     private int[] mCurrentUserProfiles = new int[] { UserHandle.USER_SYSTEM };
 
-    private GnssLocationProvider.GpsSystemInfoProvider mGpsSystemInfoProvider;
+    private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;
 
     public LocationManagerService(Context context) {
         super();
@@ -462,7 +462,7 @@
             // Create a gps location provider
             GnssLocationProvider gnssProvider = new GnssLocationProvider(mContext, this,
                     mLocationHandler.getLooper());
-            mGpsSystemInfoProvider = gnssProvider.getGpsSystemInfoProvider();
+            mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider();
             mGnssStatusProvider = gnssProvider.getGnssStatusProvider();
             mNetInitiatedListener = gnssProvider.getNetInitiatedListener();
             addProviderLocked(gnssProvider);
@@ -990,12 +990,12 @@
     }
 
     /**
-     * Returns the system information of the GPS hardware.
+     * Returns the system information of the GNSS hardware.
      */
     @Override
-    public int getGpsYearOfHardware() {
+    public int getGnssYearOfHardware() {
         if (mGnssNavigationMessageProvider != null) {
-            return mGpsSystemInfoProvider.getGpsYearOfHardware();
+            return mGnssSystemInfoProvider.getGnssYearOfHardware();
         } else {
             return 0;
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 337f749..8c04fbc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -273,6 +273,7 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
+import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
 import static android.provider.Settings.System.FONT_SCALE;
 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
@@ -1290,6 +1291,7 @@
     String mOrigDebugApp = null;
     boolean mOrigWaitForDebugger = false;
     boolean mAlwaysFinishActivities = false;
+    boolean mLenientBackgroundCheck = false;
     boolean mForceResizableActivities;
     boolean mSupportsFreeformWindowManagement;
     boolean mSupportsPictureInPicture;
@@ -7490,7 +7492,16 @@
 
     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
         UidRecord uidRec = mActiveUids.get(uid);
-        if (uidRec == null || uidRec.idle) {
+        if (!mLenientBackgroundCheck) {
+            if (uidRec == null
+                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
+                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
+                        packageName) != AppOpsManager.MODE_ALLOWED) {
+                    return ActivityManager.APP_START_MODE_DELAYED;
+                }
+            }
+
+        } else if (uidRec == null || uidRec.idle) {
             if (callingPid >= 0) {
                 ProcessRecord proc;
                 synchronized (mPidsSelfLocked) {
@@ -11376,12 +11387,36 @@
         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
                 "setAlwaysFinish()");
 
-        Settings.Global.putInt(
-                mContext.getContentResolver(),
-                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
+        long ident = Binder.clearCallingIdentity();
+        try {
+            Settings.Global.putInt(
+                    mContext.getContentResolver(),
+                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
 
-        synchronized (this) {
-            mAlwaysFinishActivities = enabled;
+            synchronized (this) {
+                mAlwaysFinishActivities = enabled;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void setLenientBackgroundCheck(boolean enabled) {
+        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
+                "setLenientBackgroundCheck()");
+
+        long ident = Binder.clearCallingIdentity();
+        try {
+            Settings.Global.putInt(
+                    mContext.getContentResolver(),
+                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
+
+            synchronized (this) {
+                mLenientBackgroundCheck = enabled;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
@@ -12278,6 +12313,8 @@
         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
         final boolean alwaysFinishActivities =
                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
+        final boolean lenientBackgroundCheck =
+                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
         final boolean forceResizable = Settings.Global.getInt(
                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
@@ -12295,6 +12332,7 @@
             mDebugApp = mOrigDebugApp = debugApp;
             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
             mAlwaysFinishActivities = alwaysFinishActivities;
+            mLenientBackgroundCheck = lenientBackgroundCheck;
             mForceResizableActivities = forceResizable;
             mWindowManager.setForceResizableTasks(mForceResizableActivities);
             mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
@@ -14074,8 +14112,9 @@
             }
         }
         if (dumpPackage == null) {
-            if (mAlwaysFinishActivities || mController != null) {
+            if (mAlwaysFinishActivities || mLenientBackgroundCheck || mController != null) {
                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
+                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck
                         + " mController=" + mController);
             }
             if (dumpAll) {
@@ -16960,7 +16999,6 @@
             case Process.ROOT_UID:
             case Process.SYSTEM_UID:
             case Process.PHONE_UID:
-            case Process.SHELL_UID:
             case Process.BLUETOOTH_UID:
             case Process.NFC_UID:
                 isCallerSystem = true;
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 8c99739..0253976 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -62,6 +62,8 @@
                     return runUntrackAssociations(pw);
                 case "is-user-stopped":
                     return runIsUserStopped(pw);
+                case "lenient-background-check":
+                    return runLenientBackgroundCheck(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -152,6 +154,22 @@
         return 0;
     }
 
+    int runLenientBackgroundCheck(PrintWriter pw) throws RemoteException {
+        String arg = getNextArg();
+        if (arg != null) {
+            boolean state = Boolean.valueOf(arg) || "1".equals(arg);
+            mInterface.setLenientBackgroundCheck(state);
+        }
+        synchronized (mInternal) {
+            if (mInternal.mLenientBackgroundCheck) {
+                pw.println("Lenient background check enabled");
+            } else {
+                pw.println("Lenient background check disabled");
+            }
+        }
+        return 0;
+    }
+
     @Override
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
@@ -203,6 +221,8 @@
             pw.println("    Disable and clear association tracking.");
             pw.println("  is-user-stopped <USER_ID>");
             pw.println("    returns whether <USER_ID> has been stopped or not");
+            pw.println("  lenient-background-check [<true|false>]");
+            pw.println("    optionally controls lenient background check mode, returns current mode.");
         }
     }
 }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 509b1bb..acde10f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1434,10 +1434,12 @@
 
         if (mStackId == DOCKED_STACK_ID) {
             // Docked stack is always visible, except in the case where the top running activity
-            // task in the focus stack doesn't support any form of resizing.
+            // task in the focus stack doesn't support any form of resizing but we show it for the
+            // home task even though it's not resizable.
             final ActivityRecord r = focusedStack.topRunningActivityLocked();
             final TaskRecord task = r != null ? r.task : null;
-            return task == null || task.canGoInDockedStack() ? STACK_VISIBLE : STACK_INVISIBLE;
+            return task == null || task.canGoInDockedStack() || task.isHomeTask() ? STACK_VISIBLE
+                    : STACK_INVISIBLE;
         }
 
         // Find the first stack below focused stack that actually got something visible.
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c143474..9562f94 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -400,7 +400,7 @@
 
     // The default minimal size that will be used if the activity doesn't specify its minimal size.
     // It will be calculated when the default display gets added.
-    private int mDefaultMinimalSizeOfResizeableTask = -1;
+    int mDefaultMinimalSizeOfResizeableTask = -1;
 
     // Whether tasks have moved and we need to rank the tasks before next OOM scoring
     private boolean mTaskLayersChanged = true;
@@ -2039,8 +2039,6 @@
             return true;
         }
 
-        adjustForMinimalTaskDimensions(task, bounds);
-
         // If this is a forced resize, let it go through even if the bounds is not changing,
         // as we might need a relayout due to surface size change (to/from fullscreen).
         final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
@@ -2074,7 +2072,7 @@
         // to be relaunched due to configuration change.
         boolean kept = true;
         if (overrideConfig != null) {
-            ActivityRecord r = task.topRunningActivityLocked();
+            final ActivityRecord r = task.topRunningActivityLocked();
             if (r != null) {
                 final ActivityStack stack = task.stack;
                 kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow);
@@ -2085,44 +2083,12 @@
                 }
             }
         }
-        mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig, kept, forced);
+        mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced);
 
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
         return kept;
     }
 
-    private void adjustForMinimalTaskDimensions(TaskRecord task, Rect bounds) {
-        if (bounds == null) {
-            return;
-        }
-        int minimalSize = task.mMinimalSize == -1 ? mDefaultMinimalSizeOfResizeableTask
-                : task.mMinimalSize;
-        final boolean adjustWidth = minimalSize > bounds.width();
-        final boolean adjustHeight = minimalSize > bounds.height();
-        if (!(adjustWidth || adjustHeight)) {
-            return;
-        }
-        Rect taskBounds = task.mBounds;
-        if (adjustWidth) {
-            if (taskBounds != null && bounds.right == taskBounds.right) {
-                bounds.left = bounds.right - minimalSize;
-            } else {
-                // Either left bounds match, or neither match, or the previous bounds were
-                // fullscreen and we default to keeping left.
-                bounds.right = bounds.left + minimalSize;
-            }
-        }
-        if (adjustHeight) {
-            if (taskBounds != null && bounds.bottom == taskBounds.bottom) {
-                bounds.top = bounds.bottom - minimalSize;
-            } else {
-                // Either top bounds match, or neither match, or the previous bounds were
-                // fullscreen and we default to keeping top.
-                bounds.bottom = bounds.top + minimalSize;
-            }
-        }
-    }
-
     ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
         ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
         if (activityDisplay == null) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 16fd909..37a549a 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -243,6 +243,8 @@
 
     // Bounds of the Task. null for fullscreen tasks.
     Rect mBounds = null;
+    private final Rect mTmpStableBounds = new Rect();
+    private final Rect mTmpNonDecorBounds = new Rect();
     private final Rect mTmpRect = new Rect();
     private final Rect mTmpRect2 = new Rect();
 
@@ -1313,6 +1315,38 @@
         return task;
     }
 
+    private void adjustForMinimalTaskDimensions(Rect bounds) {
+        if (bounds == null) {
+            return;
+        }
+        final int minimalSize = mMinimalSize == -1
+                ? mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask : mMinimalSize;
+        final boolean adjustWidth = minimalSize > bounds.width();
+        final boolean adjustHeight = minimalSize > bounds.height();
+        if (!(adjustWidth || adjustHeight)) {
+            return;
+        }
+
+        if (adjustWidth) {
+            if (mBounds != null && bounds.right == mBounds.right) {
+                bounds.left = bounds.right - minimalSize;
+            } else {
+                // Either left bounds match, or neither match, or the previous bounds were
+                // fullscreen and we default to keeping left.
+                bounds.right = bounds.left + minimalSize;
+            }
+        }
+        if (adjustHeight) {
+            if (mBounds != null && bounds.bottom == mBounds.bottom) {
+                bounds.top = bounds.bottom - minimalSize;
+            } else {
+                // Either top bounds match, or neither match, or the previous bounds were
+                // fullscreen and we default to keeping top.
+                bounds.bottom = bounds.top + minimalSize;
+            }
+        }
+    }
+
     /**
      * Update task's override configuration based on the bounds.
      * @param bounds The bounds of the task.
@@ -1345,20 +1379,17 @@
             mBounds = null;
             mOverrideConfig = Configuration.EMPTY;
         } else {
+            mTmpRect.set(bounds);
+            adjustForMinimalTaskDimensions(mTmpRect);
             if (mBounds == null) {
-                mBounds = new Rect(bounds);
+                mBounds = new Rect(mTmpRect);
             } else {
-                mBounds.set(bounds);
+                mBounds.set(mTmpRect);
             }
             if (stack == null || StackId.persistTaskBounds(stack.mStackId)) {
                 mLastNonFullscreenBounds = mBounds;
             }
-
-            // Stable insets need to be subtracted because we also subtract it in the fullscreen
-            // configuration.
-            mTmpRect.set(bounds);
-            subtractStableInsets(mTmpRect, insetBounds != null ? insetBounds : mTmpRect);
-            mOverrideConfig = calculateOverrideConfig(mTmpRect);
+            mOverrideConfig = calculateOverrideConfig(mTmpRect, insetBounds);
         }
 
         if (mFullscreen != oldFullscreen) {
@@ -1368,6 +1399,16 @@
         return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
     }
 
+    private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds) {
+        mTmpRect2.set(inInsetBounds);
+        mService.mWindowManager.subtractNonDecorInsets(mTmpRect2);
+        int leftInset = mTmpRect2.left - inInsetBounds.left;
+        int topInset = mTmpRect2.top - inInsetBounds.top;
+        int rightInset = inInsetBounds.right - mTmpRect2.right;
+        int bottomInset = inInsetBounds.bottom - mTmpRect2.bottom;
+        inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
+    }
+
     private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds) {
         mTmpRect2.set(inInsetBounds);
         mService.mWindowManager.subtractStableInsets(mTmpRect2);
@@ -1378,23 +1419,39 @@
         inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
     }
 
-    Configuration calculateOverrideConfig(Rect bounds) {
+    private Configuration calculateOverrideConfig(Rect bounds, Rect insetBounds) {
+        mTmpNonDecorBounds.set(bounds);
+        mTmpStableBounds.set(bounds);
+        subtractNonDecorInsets(
+                mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds);
+        subtractStableInsets(
+                mTmpStableBounds, insetBounds != null ? insetBounds : bounds);
+
+        // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area,
+        // i.e. the screen area without the system bars.
         final Configuration serviceConfig = mService.mConfiguration;
         final Configuration config = new Configuration(Configuration.EMPTY);
         // TODO(multidisplay): Update Dp to that of display stack is on.
         final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
         config.screenWidthDp =
-                Math.min((int)(bounds.width() / density), serviceConfig.screenWidthDp);
+                Math.min((int)(mTmpStableBounds.width() / density), serviceConfig.screenWidthDp);
         config.screenHeightDp =
-                Math.min((int)(bounds.height() / density), serviceConfig.screenHeightDp);
-        config.smallestScreenWidthDp =
-                Math.min(config.screenWidthDp, config.screenHeightDp);
+                Math.min((int)(mTmpStableBounds.height() / density), serviceConfig.screenHeightDp);
+        config.smallestScreenWidthDp = Math.min(config.screenWidthDp, config.screenHeightDp);
+
+        // TODO: Orientation?
         config.orientation = (config.screenWidthDp <= config.screenHeightDp)
                 ? Configuration.ORIENTATION_PORTRAIT
                 : Configuration.ORIENTATION_LANDSCAPE;
+
+        // For calculating screen layout, we need to use the non-decor inset screen area for the
+        // calculation for compatibility reasons, i.e. screen area without system bars that could
+        // never go away in Honeycomb.
+        final int compatScreenWidthDp = (int)(mTmpNonDecorBounds.width() / density);
+        final int compatScreenHeightDp = (int)(mTmpNonDecorBounds.height() / density);
         final int sl = Configuration.resetScreenLayout(serviceConfig.screenLayout);
-        int longSize = Math.max(config.screenWidthDp, config.screenHeightDp);
-        int shortSize = Math.min(config.screenWidthDp, config.screenHeightDp);
+        final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
+        final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
         config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
         return config;
     }
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index cefaa8d..05aabf1 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1500,6 +1500,9 @@
                                     if (authority.ident > highestAuthorityId) {
                                         highestAuthorityId = authority.ident;
                                     }
+                                } else {
+                                    EventLog.writeEvent(0x534e4554, "26513719", -1,
+                                            "Malformed authority");
                                 }
                             } else if (XML_TAG_LISTEN_FOR_TICKLES.equals(tagName)) {
                                 parseListenForTickles(parser);
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 1908f72..5c80d04 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -60,22 +60,8 @@
     // non-zero, which in turn ensures that the total weight is non-zero.
     private static final long AMBIENT_LIGHT_PREDICTION_TIME_MILLIS = 100;
 
-    // If true, enables the use of the current time as an auto-brightness adjustment.
-    // The basic idea here is to expand the dynamic range of auto-brightness
-    // when it is especially dark outside.  The light sensor tends to perform
-    // poorly at low light levels so we compensate for it by making an
-    // assumption about the environment.
-    private static final boolean USE_TWILIGHT_ADJUSTMENT =
-            PowerManager.useTwilightAdjustmentFeature();
-
     // Specifies the maximum magnitude of the time of day adjustment.
-    private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
-
-    // The amount of time after or before sunrise over which to start adjusting
-    // the gamma.  We want the change to happen gradually so that it is below the
-    // threshold of perceptibility and so that the adjustment has maximum effect
-    // well after dusk.
-    private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
+    private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1f;
 
     // Debounce for sampling user-initiated changes in display brightness to ensure
     // the user is satisfied with the result before storing the sample.
@@ -193,6 +179,8 @@
     private int mBrightnessAdjustmentSampleOldBrightness;
     private float mBrightnessAdjustmentSampleOldGamma;
 
+    private boolean mUseTwilight;
+
     public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
             SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
             int brightnessMin, int brightnessMax, float dozeScaleFactor,
@@ -221,10 +209,6 @@
         if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
             mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
         }
-
-        if (USE_TWILIGHT_ADJUSTMENT) {
-            mTwilight.registerListener(mTwilightListener, mHandler);
-        }
     }
 
     public int getAutomaticScreenBrightness() {
@@ -235,7 +219,7 @@
     }
 
     public void configure(boolean enable, float adjustment, boolean dozing,
-            boolean userInitiatedChange) {
+            boolean userInitiatedChange, boolean useTwilight) {
         // While dozing, the application processor may be suspended which will prevent us from
         // receiving new information from the light sensor. On some devices, we may be able to
         // switch to a wake-up light sensor instead but for now we will simply disable the sensor
@@ -244,6 +228,7 @@
         mDozing = dozing;
         boolean changed = setLightSensorEnabled(enable && !dozing);
         changed |= setScreenAutoBrightnessAdjustment(adjustment);
+        changed |= setUseTwilight(useTwilight);
         if (changed) {
             updateAutoBrightness(false /*sendUpdate*/);
         }
@@ -252,6 +237,17 @@
         }
     }
 
+    private boolean setUseTwilight(boolean useTwilight) {
+        if (mUseTwilight == useTwilight) return false;
+        if (useTwilight) {
+            mTwilight.registerListener(mTwilightListener, mHandler);
+        } else {
+            mTwilight.unregisterListener(mTwilightListener);
+        }
+        mUseTwilight = useTwilight;
+        return true;
+    }
+
     public void dump(PrintWriter pw) {
         pw.println();
         pw.println("Automatic Brightness Controller Configuration:");
@@ -484,18 +480,13 @@
             }
         }
 
-        if (USE_TWILIGHT_ADJUSTMENT) {
+        if (mUseTwilight) {
             TwilightState state = mTwilight.getCurrentState();
             if (state != null && state.isNight()) {
                 final long now = System.currentTimeMillis();
-                final float earlyGamma =
-                        getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
-                final float lateGamma =
-                        getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
-                gamma *= earlyGamma * lateGamma;
+                gamma *= 1 + state.getAmount() * TWILIGHT_ADJUSTMENT_MAX_GAMMA;
                 if (DEBUG) {
-                    Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
-                            + ", lateGamma=" + lateGamma);
+                    Slog.d(TAG, "updateAutoBrightness: twilight amount=" + state.getAmount());
                 }
             }
         }
@@ -579,25 +570,6 @@
         }
     }
 
-    private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
-        if (lastSunset < 0 || nextSunrise < 0
-                || now < lastSunset || now > nextSunrise) {
-            return 1.0f;
-        }
-
-        if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
-            return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
-                    (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
-        }
-
-        if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
-            return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
-                    (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
-        }
-
-        return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
-    }
-
     private final class AutomaticBrightnessHandler extends Handler {
         public AutomaticBrightnessHandler(Looper looper) {
             super(looper, null, true /*async*/);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 1038d97..1ed7070 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -615,7 +615,7 @@
                     && mPowerRequest.brightnessSetByUser;
             mAutomaticBrightnessController.configure(autoBrightnessEnabled,
                     mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
-                    userInitiatedChange);
+                    userInitiatedChange, mPowerRequest.useTwilight);
         }
 
         // Apply brightness boost.
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 57cede8..811c947 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -78,13 +78,15 @@
  * Any function with the suffix 'Locked' also needs to lock on {@link #mJobs}.
  * @hide
  */
-public class JobSchedulerService extends com.android.server.SystemService
+public final class JobSchedulerService extends com.android.server.SystemService
         implements StateChangedListener, JobCompletedListener {
     public static final boolean DEBUG = false;
     /** The number of concurrent jobs we run at one time. */
     private static final int MAX_JOB_CONTEXTS_COUNT
             = ActivityManager.isLowRamDeviceStatic() ? 3 : 6;
     static final String TAG = "JobSchedulerService";
+    /** Global local for all job scheduler state. */
+    final Object mLock = new Object();
     /** Master list of jobs. */
     final JobStore mJobs;
 
@@ -207,6 +209,10 @@
         }
     };
 
+    public Object getLock() {
+        return mLock;
+    }
+
     @Override
     public void onStartUser(int userHandle) {
         mStartedUsers.add(userHandle);
@@ -231,7 +237,7 @@
     }
 
     public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId) {
-        JobStatus jobStatus = new JobStatus(job, uId, packageName, userId);
+        JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId);
         try {
             if (ActivityManagerNative.getDefault().getAppStartMode(uId,
                     job.getService().getPackageName()) == ActivityManager.APP_START_MODE_DISABLED) {
@@ -243,7 +249,7 @@
         }
         if (DEBUG) Slog.d(TAG, "SCHEDULE: " + jobStatus.toShortString());
         JobStatus toCancel;
-        synchronized (mJobs) {
+        synchronized (mLock) {
             toCancel = mJobs.getJobByUidAndJobId(uId, job.getId());
         }
         startTrackingJob(jobStatus, toCancel);
@@ -256,7 +262,7 @@
 
     public List<JobInfo> getPendingJobs(int uid) {
         ArrayList<JobInfo> outList = new ArrayList<JobInfo>();
-        synchronized (mJobs) {
+        synchronized (mLock) {
             ArraySet<JobStatus> jobs = mJobs.getJobs();
             for (int i=0; i<jobs.size(); i++) {
                 JobStatus job = jobs.valueAt(i);
@@ -270,7 +276,7 @@
 
     void cancelJobsForUser(int userHandle) {
         List<JobStatus> jobsForUser;
-        synchronized (mJobs) {
+        synchronized (mLock) {
             jobsForUser = mJobs.getJobsByUser(userHandle);
         }
         for (int i=0; i<jobsForUser.size(); i++) {
@@ -289,7 +295,7 @@
      */
     public void cancelJobsForUid(int uid, boolean forceAll) {
         List<JobStatus> jobsForUid;
-        synchronized (mJobs) {
+        synchronized (mLock) {
             jobsForUid = mJobs.getJobsByUid(uid);
         }
         for (int i=0; i<jobsForUid.size(); i++) {
@@ -317,7 +323,7 @@
      */
     public void cancelJob(int uid, int jobId) {
         JobStatus toCancel;
-        synchronized (mJobs) {
+        synchronized (mLock) {
             toCancel = mJobs.getJobByUidAndJobId(uid, jobId);
         }
         if (toCancel != null) {
@@ -328,7 +334,7 @@
     private void cancelJobImpl(JobStatus cancelled) {
         if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
         stopTrackingJob(cancelled, true /* writeBack */);
-        synchronized (mJobs) {
+        synchronized (mLock) {
             // Remove from pending queue.
             mPendingJobs.remove(cancelled);
             // Cancel if running.
@@ -340,7 +346,7 @@
     void updateIdleMode(boolean enabled) {
         boolean changed = false;
         boolean rocking;
-        synchronized (mJobs) {
+        synchronized (mLock) {
             if (mDeviceIdleMode != enabled) {
                 changed = true;
             }
@@ -352,7 +358,7 @@
                     mControllers.get(i).deviceIdleModeChanged(enabled);
                 }
             }
-            synchronized (mJobs) {
+            synchronized (mLock) {
                 mDeviceIdleMode = enabled;
                 if (enabled) {
                     // When becoming idle, make sure no jobs are actively running.
@@ -451,7 +457,7 @@
                 // ignored; both services live in system_server
             }
         } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
-            synchronized (mJobs) {
+            synchronized (mLock) {
                 // Let's go!
                 mReadyToRock = true;
                 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
@@ -470,7 +476,7 @@
                     JobStatus job = jobs.valueAt(i);
                     for (int controller=0; controller<mControllers.size(); controller++) {
                         mControllers.get(controller).deviceIdleModeChanged(mDeviceIdleMode);
-                        mControllers.get(controller).maybeStartTrackingJob(job, null);
+                        mControllers.get(controller).maybeStartTrackingJobLocked(job, null);
                     }
                 }
                 // GO GO GO!
@@ -485,19 +491,16 @@
      * about.
      */
     private void startTrackingJob(JobStatus jobStatus, JobStatus lastJob) {
-        boolean update;
-        boolean rocking;
-        synchronized (mJobs) {
-            update = mJobs.add(jobStatus);
-            rocking = mReadyToRock;
-        }
-        if (rocking) {
-            for (int i=0; i<mControllers.size(); i++) {
-                StateController controller = mControllers.get(i);
-                if (update) {
-                    controller.maybeStopTrackingJob(jobStatus, true);
+        synchronized (mLock) {
+            final boolean update = mJobs.add(jobStatus);
+            if (mReadyToRock) {
+                for (int i = 0; i < mControllers.size(); i++) {
+                    StateController controller = mControllers.get(i);
+                    if (update) {
+                        controller.maybeStopTrackingJobLocked(jobStatus, true);
+                    }
+                    controller.maybeStartTrackingJobLocked(jobStatus, lastJob);
                 }
-                controller.maybeStartTrackingJob(jobStatus, lastJob);
             }
         }
     }
@@ -507,20 +510,17 @@
      * object removed.
      */
     private boolean stopTrackingJob(JobStatus jobStatus, boolean writeBack) {
-        boolean removed;
-        boolean rocking;
-        synchronized (mJobs) {
+        synchronized (mLock) {
             // Remove from store as well as controllers.
-            removed = mJobs.remove(jobStatus, writeBack);
-            rocking = mReadyToRock;
-        }
-        if (removed && rocking) {
-            for (int i=0; i<mControllers.size(); i++) {
-                StateController controller = mControllers.get(i);
-                controller.maybeStopTrackingJob(jobStatus, false);
+            final boolean removed = mJobs.remove(jobStatus, writeBack);
+            if (removed && mReadyToRock) {
+                for (int i=0; i<mControllers.size(); i++) {
+                    StateController controller = mControllers.get(i);
+                    controller.maybeStopTrackingJobLocked(jobStatus, false);
+                }
             }
+            return removed;
         }
-        return removed;
     }
 
     private boolean stopJobOnServiceContextLocked(JobStatus job, int reason) {
@@ -693,14 +693,14 @@
 
         @Override
         public void handleMessage(Message message) {
-            synchronized (mJobs) {
+            synchronized (mLock) {
                 if (!mReadyToRock) {
                     return;
                 }
             }
             switch (message.what) {
                 case MSG_JOB_EXPIRED:
-                    synchronized (mJobs) {
+                    synchronized (mLock) {
                         JobStatus runNow = (JobStatus) message.obj;
                         // runNow can be null, which is a controller's way of indicating that its
                         // state is such that all ready jobs should be run immediately.
@@ -712,7 +712,7 @@
                     }
                     break;
                 case MSG_CHECK_JOB:
-                    synchronized (mJobs) {
+                    synchronized (mLock) {
                         if (mReportedActive) {
                             // if jobs are currently being run, queue all ready jobs for execution.
                             queueReadyJobsForExecutionLockedH();
@@ -723,7 +723,7 @@
                     }
                     break;
                 case MSG_CHECK_JOB_GREEDY:
-                    synchronized (mJobs) {
+                    synchronized (mLock) {
                         queueReadyJobsForExecutionLockedH();
                     }
                     break;
@@ -753,7 +753,7 @@
                         Slog.d(TAG, "    queued " + job.toShortString());
                     }
                     mPendingJobs.add(job);
-                } else if (areJobConstraintsNotSatisfied(job)) {
+                } else if (areJobConstraintsNotSatisfiedLocked(job)) {
                     stopJobOnServiceContextLocked(job,
                             JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
                 }
@@ -820,7 +820,7 @@
                         runnableJobs = new ArrayList<>();
                     }
                     runnableJobs.add(job);
-                } else if (areJobConstraintsNotSatisfied(job)) {
+                } else if (areJobConstraintsNotSatisfiedLocked(job)) {
                     stopJobOnServiceContextLocked(job,
                             JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
                 }
@@ -869,7 +869,7 @@
          *      - It's not ready
          *      - It's running on a JSC.
          */
-        private boolean areJobConstraintsNotSatisfied(JobStatus job) {
+        private boolean areJobConstraintsNotSatisfiedLocked(JobStatus job) {
             return !job.isReady() && isCurrentlyActiveLocked(job);
         }
 
@@ -879,7 +879,7 @@
          * here is where we decide whether to actually execute it.
          */
         private void maybeRunPendingJobsH() {
-            synchronized (mJobs) {
+            synchronized (mLock) {
                 if (mDeviceIdleMode) {
                     // If device is idle, we will not schedule jobs to run.
                     return;
@@ -887,7 +887,7 @@
                 if (DEBUG) {
                     Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs.");
                 }
-                assignJobsToContextsH();
+                assignJobsToContextsLocked();
                 reportActive();
             }
         }
@@ -899,7 +899,7 @@
      * run higher priority ones.
      * Lock on mJobs before calling this function.
      */
-    private void assignJobsToContextsH() {
+    private void assignJobsToContextsLocked() {
         if (DEBUG) {
             Slog.d(TAG, printPendingQueue());
         }
@@ -984,7 +984,7 @@
                     }
                     for (int ic=0; ic<mControllers.size(); ic++) {
                         StateController controller = mControllers.get(ic);
-                        controller.prepareForExecution(contextIdToJobMap[i]);
+                        controller.prepareForExecutionLocked(contextIdToJobMap[i]);
                     }
                     if (!mActiveServices.get(i).executeRunnableJob(contextIdToJobMap[i])) {
                         Slog.d(TAG, "Error executing " + contextIdToJobMap[i]);
@@ -1185,7 +1185,7 @@
 
     void dumpInternal(PrintWriter pw) {
         final long now = SystemClock.elapsedRealtime();
-        synchronized (mJobs) {
+        synchronized (mLock) {
             pw.print("Started users: ");
             for (int i=0; i<mStartedUsers.size(); i++) {
                 pw.print("u" + mStartedUsers.get(i) + " ");
@@ -1216,7 +1216,7 @@
             }
             for (int i=0; i<mControllers.size(); i++) {
                 pw.println();
-                mControllers.get(i).dumpControllerState(pw);
+                mControllers.get(i).dumpControllerStateLocked(pw);
             }
             pw.println();
             pw.println(printPendingQueue());
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index b249739..48549ce 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -103,6 +103,7 @@
     private final JobCompletedListener mCompletedListener;
     /** Used for service binding, etc. */
     private final Context mContext;
+    private final Object mLock;
     private final IBatteryStats mBatteryStats;
     private PowerManager.WakeLock mWakeLock;
 
@@ -124,7 +125,6 @@
     private int mPreferredUid;
     IJobService service;
 
-    private final Object mLock = new Object();
     /**
      * Whether this context is free. This is set to false at the start of execution, and reset to
      * true when execution is complete.
@@ -137,13 +137,14 @@
     private long mTimeoutElapsed;
 
     JobServiceContext(JobSchedulerService service, IBatteryStats batteryStats, Looper looper) {
-        this(service.getContext(), batteryStats, service, looper);
+        this(service.getContext(), service.getLock(), batteryStats, service, looper);
     }
 
     @VisibleForTesting
-    JobServiceContext(Context context, IBatteryStats batteryStats,
+    JobServiceContext(Context context, Object lock, IBatteryStats batteryStats,
                       JobCompletedListener completedListener, Looper looper) {
         mContext = context;
+        mLock = lock;
         mBatteryStats = batteryStats;
         mCallbackHandler = new JobServiceHandler(looper);
         mCompletedListener = completedListener;
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 3565fc1..6020247 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -44,7 +44,6 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -70,6 +69,7 @@
     /** Threshold to adjust how often we want to write to the db. */
     private static final int MAX_OPS_BEFORE_WRITE = 1;
     final ArraySet<JobStatus> mJobSet;
+    final Object mLock;
     final Context mContext;
 
     private int mDirtyOperations;
@@ -85,7 +85,7 @@
         synchronized (sSingletonLock) {
             if (sSingleton == null) {
                 sSingleton = new JobStore(jobManagerService.getContext(),
-                        Environment.getDataDirectory());
+                        jobManagerService.getLock(), Environment.getDataDirectory());
             }
             return sSingleton;
         }
@@ -96,7 +96,7 @@
      */
     @VisibleForTesting
     public static JobStore initAndGetForTesting(Context context, File dataDir) {
-        JobStore jobStoreUnderTest = new JobStore(context, dataDir);
+        JobStore jobStoreUnderTest = new JobStore(context, new Object(), dataDir);
         jobStoreUnderTest.clear();
         return jobStoreUnderTest;
     }
@@ -104,7 +104,8 @@
     /**
      * Construct the instance of the job store. This results in a blocking read from disk.
      */
-    private JobStore(Context context, File dataDir) {
+    private JobStore(Context context, Object lock, File dataDir) {
+        mLock = lock;
         mContext = context;
         mDirtyOperations = 0;
 
@@ -266,14 +267,14 @@
 
     /**
      * Runnable that writes {@link #mJobSet} out to xml.
-     * NOTE: This Runnable locks on JobStore.this
+     * NOTE: This Runnable locks on mLock
      */
     private class WriteJobsMapToDiskRunnable implements Runnable {
         @Override
         public void run() {
             final long startElapsed = SystemClock.elapsedRealtime();
             List<JobStatus> mStoreCopy = new ArrayList<JobStatus>();
-            synchronized (JobStore.this) {
+            synchronized (mLock) {
                 // Copy over the jobs so we can release the lock before writing.
                 for (int i=0; i<mJobSet.size(); i++) {
                     JobStatus jobStatus = mJobSet.valueAt(i);
@@ -454,7 +455,7 @@
             try {
                 List<JobStatus> jobs;
                 FileInputStream fis = mJobsFile.openRead();
-                synchronized (JobStore.this) {
+                synchronized (mLock) {
                     jobs = readJobMapImpl(fis);
                     if (jobs != null) {
                         for (int i=0; i<jobs.size(); i++) {
@@ -678,8 +679,8 @@
             parser.nextTag(); // Consume </extras>
 
             JobStatus js = new JobStatus(
-                    jobBuilder.build(), uid, sourcePackageName, sourceUserId, elapsedRuntimes.first,
-                    elapsedRuntimes.second);
+                    jobBuilder.build(), uid, sourcePackageName, sourceUserId,
+                    elapsedRuntimes.first, elapsedRuntimes.second);
             return js;
         }
 
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 5f3da75..f0c579f 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -48,59 +48,56 @@
     public static AppIdleController get(JobSchedulerService service) {
         synchronized (sCreationLock) {
             if (sController == null) {
-                sController = new AppIdleController(service, service.getContext());
+                sController = new AppIdleController(service, service.getContext(),
+                        service.getLock());
             }
             return sController;
         }
     }
 
-    private AppIdleController(StateChangedListener stateChangedListener, Context context) {
-        super(stateChangedListener, context);
+    private AppIdleController(StateChangedListener stateChangedListener, Context context,
+            Object lock) {
+        super(stateChangedListener, context, lock);
         mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class);
         mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn();
         mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
     }
 
     @Override
-    public void maybeStartTrackingJob(JobStatus jobStatus, JobStatus lastJob) {
-        synchronized (mTrackedTasks) {
-            mTrackedTasks.add(jobStatus);
-            String packageName = jobStatus.getSourcePackageName();
-            final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
-                    jobStatus.getSourceUid(), jobStatus.getSourceUserId());
-            if (DEBUG) {
-                Slog.d(LOG_TAG, "Start tracking, setting idle state of "
-                        + packageName + " to " + appIdle);
-            }
-            jobStatus.appNotIdleConstraintSatisfied.set(!appIdle);
+    public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
+        mTrackedTasks.add(jobStatus);
+        String packageName = jobStatus.getSourcePackageName();
+        final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
+                jobStatus.getSourceUid(), jobStatus.getSourceUserId());
+        if (DEBUG) {
+            Slog.d(LOG_TAG, "Start tracking, setting idle state of "
+                    + packageName + " to " + appIdle);
         }
+        jobStatus.setAppNotIdleConstraintSatisfied(!appIdle);
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus jobStatus, boolean forUpdate) {
-        synchronized (mTrackedTasks) {
-            mTrackedTasks.remove(jobStatus);
-        }
+    public void maybeStopTrackingJobLocked(JobStatus jobStatus, boolean forUpdate) {
+        mTrackedTasks.remove(jobStatus);
     }
 
     @Override
-    public void dumpControllerState(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw) {
         pw.println("AppIdle");
         pw.println("Parole On: " + mAppIdleParoleOn);
-        synchronized (mTrackedTasks) {
-            for (JobStatus task : mTrackedTasks) {
-                pw.print(task.getSourcePackageName());
-                pw.print(":idle=" + !task.appNotIdleConstraintSatisfied.get());
-                pw.print(", ");
-            }
-            pw.println();
+        for (JobStatus task : mTrackedTasks) {
+            pw.print(task.getSourcePackageName());
+            pw.print(":idle="
+                    + ((task.satisfiedConstraints&JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0));
+            pw.print(", ");
         }
+        pw.println();
     }
 
     void setAppIdleParoleOn(boolean isAppIdleParoleOn) {
         // Flag if any app's idle state has changed
         boolean changed = false;
-        synchronized (mTrackedTasks) {
+        synchronized (mLock) {
             if (mAppIdleParoleOn == isAppIdleParoleOn) {
                 return;
             }
@@ -112,8 +109,7 @@
                 if (DEBUG) {
                     Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle);
                 }
-                if (task.appNotIdleConstraintSatisfied.get() == appIdle) {
-                    task.appNotIdleConstraintSatisfied.set(!appIdle);
+                if (task.setAppNotIdleConstraintSatisfied(!appIdle)) {
                     changed = true;
                 }
             }
@@ -128,19 +124,18 @@
         @Override
         public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
             boolean changed = false;
-            synchronized (mTrackedTasks) {
+            synchronized (mLock) {
                 if (mAppIdleParoleOn) {
                     return;
                 }
                 for (JobStatus task : mTrackedTasks) {
                     if (task.getSourcePackageName().equals(packageName)
                             && task.getSourceUserId() == userId) {
-                        if (task.appNotIdleConstraintSatisfied.get() != !idle) {
+                        if (task.setAppNotIdleConstraintSatisfied(!idle)) {
                             if (DEBUG) {
                                 Slog.d(LOG_TAG, "App Idle state changed, setting idle state of "
                                         + packageName + " to " + idle);
                             }
-                            task.appNotIdleConstraintSatisfied.set(!idle);
                             changed = true;
                         }
                     }
diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
index b322a3e..ac9f425 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -53,7 +53,7 @@
         synchronized (sCreationLock) {
             if (sController == null) {
                 sController = new BatteryController(taskManagerService,
-                        taskManagerService.getContext());
+                        taskManagerService.getContext(), taskManagerService.getLock());
             }
         }
         return sController;
@@ -67,32 +67,29 @@
     @VisibleForTesting
     public static BatteryController getForTesting(StateChangedListener stateChangedListener,
                                            Context context) {
-        return new BatteryController(stateChangedListener, context);
+        return new BatteryController(stateChangedListener, context, new Object());
     }
 
-    private BatteryController(StateChangedListener stateChangedListener, Context context) {
-        super(stateChangedListener, context);
+    private BatteryController(StateChangedListener stateChangedListener, Context context,
+            Object lock) {
+        super(stateChangedListener, context, lock);
         mChargeTracker = new ChargingTracker();
         mChargeTracker.startTracking();
     }
 
     @Override
-    public void maybeStartTrackingJob(JobStatus taskStatus, JobStatus lastJob) {
+    public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) {
         final boolean isOnStablePower = mChargeTracker.isOnStablePower();
         if (taskStatus.hasChargingConstraint()) {
-            synchronized (mTrackedTasks) {
-                mTrackedTasks.add(taskStatus);
-                taskStatus.chargingConstraintSatisfied.set(isOnStablePower);
-            }
+            mTrackedTasks.add(taskStatus);
+            taskStatus.setChargingConstraintSatisfied(isOnStablePower);
         }
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus taskStatus, boolean forUpdate) {
+    public void maybeStopTrackingJobLocked(JobStatus taskStatus, boolean forUpdate) {
         if (taskStatus.hasChargingConstraint()) {
-            synchronized (mTrackedTasks) {
-                mTrackedTasks.remove(taskStatus);
-            }
+            mTrackedTasks.remove(taskStatus);
         }
     }
 
@@ -102,9 +99,9 @@
             Slog.d(TAG, "maybeReportNewChargingState: " + stablePower);
         }
         boolean reportChange = false;
-        synchronized (mTrackedTasks) {
+        synchronized (mLock) {
             for (JobStatus ts : mTrackedTasks) {
-                boolean previous = ts.chargingConstraintSatisfied.getAndSet(stablePower);
+                boolean previous = ts.setChargingConstraintSatisfied(stablePower);
                 if (previous != stablePower) {
                     reportChange = true;
                 }
@@ -197,18 +194,16 @@
     }
 
     @Override
-    public void dumpControllerState(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw) {
         pw.println("Batt.");
         pw.println("Stable power: " + mChargeTracker.isOnStablePower());
-        synchronized (mTrackedTasks) {
-            Iterator<JobStatus> it = mTrackedTasks.iterator();
-            if (it.hasNext()) {
-                pw.print(String.valueOf(it.next().hashCode()));
-            }
-            while (it.hasNext()) {
-                pw.print("," + String.valueOf(it.next().hashCode()));
-            }
-            pw.println();
+        Iterator<JobStatus> it = mTrackedTasks.iterator();
+        if (it.hasNext()) {
+            pw.print(String.valueOf(it.next().hashCode()));
         }
+        while (it.hasNext()) {
+            pw.print("," + String.valueOf(it.next().hashCode()));
+        }
+        pw.println();
     }
 }
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index b84658a..bd06645 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -58,14 +58,15 @@
     public static ConnectivityController get(JobSchedulerService jms) {
         synchronized (sCreationLock) {
             if (mSingleton == null) {
-                mSingleton = new ConnectivityController(jms, jms.getContext());
+                mSingleton = new ConnectivityController(jms, jms.getContext(), jms.getLock());
             }
             return mSingleton;
         }
     }
 
-    private ConnectivityController(StateChangedListener stateChangedListener, Context context) {
-        super(stateChangedListener, context);
+    private ConnectivityController(StateChangedListener stateChangedListener, Context context,
+            Object lock) {
+        super(stateChangedListener, context, lock);
         // Register connectivity changed BR.
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
@@ -82,22 +83,18 @@
     }
 
     @Override
-    public void maybeStartTrackingJob(JobStatus jobStatus, JobStatus lastJob) {
+    public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
         if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
-            synchronized (mTrackedJobs) {
-                jobStatus.connectivityConstraintSatisfied.set(mNetworkConnected);
-                jobStatus.unmeteredConstraintSatisfied.set(mNetworkUnmetered);
-                mTrackedJobs.add(jobStatus);
-            }
+            jobStatus.setConnectivityConstraintSatisfied(mNetworkConnected);
+            jobStatus.setUnmeteredConstraintSatisfied(mNetworkUnmetered);
+            mTrackedJobs.add(jobStatus);
         }
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus jobStatus, boolean forUpdate) {
+    public void maybeStopTrackingJobLocked(JobStatus jobStatus, boolean forUpdate) {
         if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
-            synchronized (mTrackedJobs) {
-                mTrackedJobs.remove(jobStatus);
-            }
+            mTrackedJobs.remove(jobStatus);
         }
     }
 
@@ -105,18 +102,14 @@
      * @param userId Id of the user for whom we are updating the connectivity state.
      */
     private void updateTrackedJobs(int userId) {
-        synchronized (mTrackedJobs) {
+        synchronized (mLock) {
             boolean changed = false;
             for (JobStatus js : mTrackedJobs) {
                 if (js.getUserId() != userId) {
                     continue;
                 }
-                boolean prevIsConnected =
-                        js.connectivityConstraintSatisfied.getAndSet(mNetworkConnected);
-                boolean prevIsMetered = js.unmeteredConstraintSatisfied.getAndSet(mNetworkUnmetered);
-                if (prevIsConnected != mNetworkConnected || prevIsMetered != mNetworkUnmetered) {
-                    changed = true;
-                }
+                changed |= js.setConnectivityConstraintSatisfied(mNetworkConnected);
+                changed |= js.setUnmeteredConstraintSatisfied(mNetworkUnmetered);
             }
             if (changed) {
                 mStateChangedListener.onControllerStateChanged();
@@ -128,7 +121,7 @@
      * We know the network has just come up. We want to run any jobs that are ready.
      */
     public synchronized void onNetworkActive() {
-        synchronized (mTrackedJobs) {
+        synchronized (mLock) {
             for (JobStatus js : mTrackedJobs) {
                 if (js.isReady()) {
                     if (DEBUG) {
@@ -188,7 +181,7 @@
     };
 
     @Override
-    public void dumpControllerState(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw) {
         pw.println("Conn.");
         pw.println("connected: " + mNetworkConnected + " unmetered: " + mNetworkUnmetered);
         for (JobStatus js: mTrackedJobs) {
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
index 212cc94..c5cf30f 100644
--- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -57,7 +57,7 @@
         synchronized (sCreationLock) {
             if (sController == null) {
                 sController = new ContentObserverController(taskManagerService,
-                        taskManagerService.getContext());
+                        taskManagerService.getContext(), taskManagerService.getLock());
             }
         }
         return sController;
@@ -66,95 +66,90 @@
     @VisibleForTesting
     public static ContentObserverController getForTesting(StateChangedListener stateChangedListener,
                                            Context context) {
-        return new ContentObserverController(stateChangedListener, context);
+        return new ContentObserverController(stateChangedListener, context, new Object());
     }
 
-    private ContentObserverController(StateChangedListener stateChangedListener, Context context) {
-        super(stateChangedListener, context);
+    private ContentObserverController(StateChangedListener stateChangedListener, Context context,
+                Object lock) {
+        super(stateChangedListener, context, lock);
     }
 
     @Override
-    public void maybeStartTrackingJob(JobStatus taskStatus, JobStatus lastJob) {
+    public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) {
         if (taskStatus.hasContentTriggerConstraint()) {
-            synchronized (mTrackedTasks) {
-                if (taskStatus.contentObserverJobInstance == null) {
-                    taskStatus.contentObserverJobInstance = new JobInstance(taskStatus);
-                }
-                mTrackedTasks.add(taskStatus);
-                boolean havePendingUris = false;
-                // If there is a previous job associated with the new job, propagate over
-                // any pending content URI trigger reports.
-                if (lastJob != null && lastJob.contentObserverJobInstance != null
-                        && lastJob.contentObserverJobInstance
-                        != taskStatus.contentObserverJobInstance
-                        && lastJob.contentObserverJobInstance.mChangedAuthorities != null) {
-                    havePendingUris = true;
+            if (taskStatus.contentObserverJobInstance == null) {
+                taskStatus.contentObserverJobInstance = new JobInstance(taskStatus);
+            }
+            mTrackedTasks.add(taskStatus);
+            boolean havePendingUris = false;
+            // If there is a previous job associated with the new job, propagate over
+            // any pending content URI trigger reports.
+            if (lastJob != null && lastJob.contentObserverJobInstance != null
+                    && lastJob.contentObserverJobInstance
+                    != taskStatus.contentObserverJobInstance
+                    && lastJob.contentObserverJobInstance.mChangedAuthorities != null) {
+                havePendingUris = true;
+                taskStatus.contentObserverJobInstance.mChangedAuthorities
+                        = lastJob.contentObserverJobInstance.mChangedAuthorities;
+                taskStatus.contentObserverJobInstance.mChangedUris
+                        = lastJob.contentObserverJobInstance.mChangedUris;
+                lastJob.contentObserverJobInstance.mChangedAuthorities = null;
+                lastJob.contentObserverJobInstance.mChangedUris = null;
+            }
+            // If we have previously reported changed authorities/uris, then we failed
+            // to complete the job with them so will re-record them to report again.
+            if (taskStatus.changedAuthorities != null) {
+                havePendingUris = true;
+                if (taskStatus.contentObserverJobInstance.mChangedAuthorities == null) {
                     taskStatus.contentObserverJobInstance.mChangedAuthorities
-                            = lastJob.contentObserverJobInstance.mChangedAuthorities;
-                    taskStatus.contentObserverJobInstance.mChangedUris
-                            = lastJob.contentObserverJobInstance.mChangedUris;
-                    lastJob.contentObserverJobInstance.mChangedAuthorities = null;
-                    lastJob.contentObserverJobInstance.mChangedUris = null;
+                            = new ArraySet<>();
                 }
-                // If we have previously reported changed authorities/uris, then we failed
-                // to complete the job with them so will re-record them to report again.
-                if (taskStatus.changedAuthorities != null) {
-                    havePendingUris = true;
-                    if (taskStatus.contentObserverJobInstance.mChangedAuthorities == null) {
-                        taskStatus.contentObserverJobInstance.mChangedAuthorities
-                                = new ArraySet<>();
+                for (String auth : taskStatus.changedAuthorities) {
+                    taskStatus.contentObserverJobInstance.mChangedAuthorities.add(auth);
+                }
+                if (taskStatus.changedUris != null) {
+                    if (taskStatus.contentObserverJobInstance.mChangedUris == null) {
+                        taskStatus.contentObserverJobInstance.mChangedUris = new ArraySet<>();
                     }
-                    for (String auth : taskStatus.changedAuthorities) {
-                        taskStatus.contentObserverJobInstance.mChangedAuthorities.add(auth);
+                    for (Uri uri : taskStatus.changedUris) {
+                        taskStatus.contentObserverJobInstance.mChangedUris.add(uri);
                     }
-                    if (taskStatus.changedUris != null) {
-                        if (taskStatus.contentObserverJobInstance.mChangedUris == null) {
-                            taskStatus.contentObserverJobInstance.mChangedUris = new ArraySet<>();
-                        }
-                        for (Uri uri : taskStatus.changedUris) {
-                            taskStatus.contentObserverJobInstance.mChangedUris.add(uri);
-                        }
-                    }
-                    taskStatus.changedAuthorities = null;
-                    taskStatus.changedUris = null;
                 }
                 taskStatus.changedAuthorities = null;
                 taskStatus.changedUris = null;
-                taskStatus.contentTriggerConstraintSatisfied.set(havePendingUris);
+            }
+            taskStatus.changedAuthorities = null;
+            taskStatus.changedUris = null;
+            taskStatus.setContentTriggerConstraintSatisfied(havePendingUris);
+        }
+    }
+
+    @Override
+    public void prepareForExecutionLocked(JobStatus taskStatus) {
+        if (taskStatus.hasContentTriggerConstraint()) {
+            if (taskStatus.contentObserverJobInstance != null) {
+                taskStatus.changedUris = taskStatus.contentObserverJobInstance.mChangedUris;
+                taskStatus.changedAuthorities
+                        = taskStatus.contentObserverJobInstance.mChangedAuthorities;
+                taskStatus.contentObserverJobInstance.mChangedUris = null;
+                taskStatus.contentObserverJobInstance.mChangedAuthorities = null;
             }
         }
     }
 
     @Override
-    public void prepareForExecution(JobStatus taskStatus) {
+    public void maybeStopTrackingJobLocked(JobStatus taskStatus, boolean forUpdate) {
         if (taskStatus.hasContentTriggerConstraint()) {
-            synchronized (mTrackedTasks) {
+            if (!forUpdate) {
+                // We won't do this reset if being called for an update, because
+                // we know it will be immediately followed by maybeStartTrackingJobLocked...
+                // and we don't want to lose any content changes in-between.
                 if (taskStatus.contentObserverJobInstance != null) {
-                    taskStatus.changedUris = taskStatus.contentObserverJobInstance.mChangedUris;
-                    taskStatus.changedAuthorities
-                            = taskStatus.contentObserverJobInstance.mChangedAuthorities;
-                    taskStatus.contentObserverJobInstance.mChangedUris = null;
-                    taskStatus.contentObserverJobInstance.mChangedAuthorities = null;
+                    taskStatus.contentObserverJobInstance.detach();
+                    taskStatus.contentObserverJobInstance = null;
                 }
             }
-        }
-    }
-
-    @Override
-    public void maybeStopTrackingJob(JobStatus taskStatus, boolean forUpdate) {
-        if (taskStatus.hasContentTriggerConstraint()) {
-            synchronized (mTrackedTasks) {
-                if (!forUpdate) {
-                    // We won't do this reset if being called for an update, because
-                    // we know it will be immediately followed by maybeStartTrackingJob...
-                    // and we don't want to lose any content changes in-between.
-                    if (taskStatus.contentObserverJobInstance != null) {
-                        taskStatus.contentObserverJobInstance.detach();
-                        taskStatus.contentObserverJobInstance = null;
-                    }
-                }
-                mTrackedTasks.remove(taskStatus);
-            }
+            mTrackedTasks.remove(taskStatus);
         }
     }
 
@@ -162,7 +157,7 @@
     public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
         if (failureToReschedule.hasContentTriggerConstraint()
                 && newJob.hasContentTriggerConstraint()) {
-            synchronized (mTrackedTasks) {
+            synchronized (mLock) {
                 // Our job has failed, and we are scheduling a new job for it.
                 // Copy the last reported content changes in to the new job, so when
                 // we schedule the new one we will pick them up and report them again.
@@ -184,7 +179,7 @@
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             boolean reportChange = false;
-            synchronized (mTrackedTasks) {
+            synchronized (mLock) {
                 final int N = mJobs.size();
                 for (int i=0; i<N; i++) {
                     JobInstance inst = mJobs.get(i);
@@ -198,9 +193,7 @@
                         inst.mChangedAuthorities = new ArraySet<>();
                     }
                     inst.mChangedAuthorities.add(uri.getAuthority());
-                    boolean previous
-                            = inst.mJobStatus.contentTriggerConstraintSatisfied.getAndSet(true);
-                    if (!previous) {
+                    if (inst.mJobStatus.setContentTriggerConstraintSatisfied(true)) {
                         reportChange = true;
                     }
                 }
@@ -254,50 +247,48 @@
     }
 
     @Override
-    public void dumpControllerState(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw) {
         pw.println("Content.");
-        synchronized (mTrackedTasks) {
-            Iterator<JobStatus> it = mTrackedTasks.iterator();
-            if (it.hasNext()) {
-                pw.print(String.valueOf(it.next().hashCode()));
-            }
-            while (it.hasNext()) {
-                pw.print("," + String.valueOf(it.next().hashCode()));
-            }
-            pw.println();
-            int N = mObservers.size();
-            if (N > 0) {
-                pw.println("URIs:");
-                for (int i = 0; i < N; i++) {
-                    ObserverInstance obs = mObservers.valueAt(i);
-                    pw.print("  ");
-                    pw.print(mObservers.keyAt(i));
-                    pw.println(":");
-                    pw.print("    ");
-                    pw.println(obs);
-                    pw.println("    Jobs:");
-                    int M = obs.mJobs.size();
-                    for (int j=0; j<M; j++) {
-                        JobInstance inst = obs.mJobs.get(j);
-                        pw.print("      ");
-                        pw.print(inst.hashCode());
-                        if (inst.mChangedAuthorities != null) {
-                            pw.println(":");
-                            pw.println("        Changed Authorities:");
-                            for (int k=0; k<inst.mChangedAuthorities.size(); k++) {
-                                pw.print("          ");
-                                pw.println(inst.mChangedAuthorities.valueAt(k));
-                            }
-                            if (inst.mChangedUris != null) {
-                                pw.println("        Changed URIs:");
-                                for (int k = 0; k<inst.mChangedUris.size(); k++) {
-                                    pw.print("          ");
-                                    pw.println(inst.mChangedUris.valueAt(k));
-                                }
-                            }
-                        } else {
-                            pw.println();
+        Iterator<JobStatus> it = mTrackedTasks.iterator();
+        if (it.hasNext()) {
+            pw.print(String.valueOf(it.next().hashCode()));
+        }
+        while (it.hasNext()) {
+            pw.print("," + String.valueOf(it.next().hashCode()));
+        }
+        pw.println();
+        int N = mObservers.size();
+        if (N > 0) {
+            pw.println("URIs:");
+            for (int i = 0; i < N; i++) {
+                ObserverInstance obs = mObservers.valueAt(i);
+                pw.print("  ");
+                pw.print(mObservers.keyAt(i));
+                pw.println(":");
+                pw.print("    ");
+                pw.println(obs);
+                pw.println("    Jobs:");
+                int M = obs.mJobs.size();
+                for (int j=0; j<M; j++) {
+                    JobInstance inst = obs.mJobs.get(j);
+                    pw.print("      ");
+                    pw.print(inst.hashCode());
+                    if (inst.mChangedAuthorities != null) {
+                        pw.println(":");
+                        pw.println("        Changed Authorities:");
+                        for (int k=0; k<inst.mChangedAuthorities.size(); k++) {
+                            pw.print("          ");
+                            pw.println(inst.mChangedAuthorities.valueAt(k));
                         }
+                        if (inst.mChangedUris != null) {
+                            pw.println("        Changed URIs:");
+                            for (int k = 0; k<inst.mChangedUris.size(); k++) {
+                                pw.print("          ");
+                                pw.println(inst.mChangedUris.valueAt(k));
+                            }
+                        }
+                    } else {
+                        pw.println();
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 9f4cdef..7638494 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -51,14 +51,15 @@
     public static IdleController get(JobSchedulerService service) {
         synchronized (sCreationLock) {
             if (sController == null) {
-                sController = new IdleController(service, service.getContext());
+                sController = new IdleController(service, service.getContext(), service.getLock());
             }
             return sController;
         }
     }
 
-    private IdleController(StateChangedListener stateChangedListener, Context context) {
-        super(stateChangedListener, context);
+    private IdleController(StateChangedListener stateChangedListener, Context context,
+                Object lock) {
+        super(stateChangedListener, context, lock);
         initIdleStateTracking();
     }
 
@@ -66,29 +67,25 @@
      * StateController interface
      */
     @Override
-    public void maybeStartTrackingJob(JobStatus taskStatus, JobStatus lastJob) {
+    public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) {
         if (taskStatus.hasIdleConstraint()) {
-            synchronized (mTrackedTasks) {
-                mTrackedTasks.add(taskStatus);
-                taskStatus.idleConstraintSatisfied.set(mIdleTracker.isIdle());
-            }
+            mTrackedTasks.add(taskStatus);
+            taskStatus.setIdleConstraintSatisfied(mIdleTracker.isIdle());
         }
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus taskStatus, boolean forUpdate) {
-        synchronized (mTrackedTasks) {
-            mTrackedTasks.remove(taskStatus);
-        }
+    public void maybeStopTrackingJobLocked(JobStatus taskStatus, boolean forUpdate) {
+        mTrackedTasks.remove(taskStatus);
     }
 
     /**
      * Interaction with the task manager service
      */
     void reportNewIdleState(boolean isIdle) {
-        synchronized (mTrackedTasks) {
+        synchronized (mLock) {
             for (JobStatus task : mTrackedTasks) {
-                task.idleConstraintSatisfied.set(isIdle);
+                task.setIdleConstraintSatisfied(isIdle);
             }
         }
         mStateChangedListener.onControllerStateChanged();
@@ -193,17 +190,15 @@
     }
 
     @Override
-    public void dumpControllerState(PrintWriter pw) {
-        synchronized (mTrackedTasks) {
-            pw.print("Idle: ");
-            pw.println(mIdleTracker.isIdle() ? "true" : "false");
-            pw.println(mTrackedTasks.size());
-            for (int i = 0; i < mTrackedTasks.size(); i++) {
-                final JobStatus js = mTrackedTasks.get(i);
-                pw.print("  ");
-                pw.print(String.valueOf(js.hashCode()).substring(0, 3));
-                pw.println("..");
-            }
+    public void dumpControllerStateLocked(PrintWriter pw) {
+        pw.print("Idle: ");
+        pw.println(mIdleTracker.isIdle() ? "true" : "false");
+        pw.println(mTrackedTasks.size());
+        for (int i = 0; i < mTrackedTasks.size(); i++) {
+            final JobStatus js = mTrackedTasks.get(i);
+            pw.print("  ");
+            pw.print(String.valueOf(js.hashCode()).substring(0, 3));
+            pw.println("..");
         }
     }
 }
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index c4d564c..f835069 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -42,10 +42,19 @@
  * but we don't enforce that so this is safer.
  * @hide
  */
-public class JobStatus {
+public final class JobStatus {
     public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
     public static final long NO_EARLIEST_RUNTIME = 0L;
 
+    static final int CONSTRAINT_CHARGING = 1<<0;
+    static final int CONSTRAINT_TIMING_DELAY = 1<<1;
+    static final int CONSTRAINT_DEADLINE = 1<<2;
+    static final int CONSTRAINT_IDLE = 1<<3;
+    static final int CONSTRAINT_UNMETERED = 1<<4;
+    static final int CONSTRAINT_CONNECTIVITY = 1<<5;
+    static final int CONSTRAINT_APP_NOT_IDLE = 1<<6;
+    static final int CONSTRAINT_CONTENT_TRIGGER = 1<<7;
+
     final JobInfo job;
     /** Uid of the package requesting this job. */
     final int callingUid;
@@ -56,15 +65,23 @@
     final int sourceUserId;
     final int sourceUid;
 
+    /**
+     * Earliest point in the future at which this job will be eligible to run. A value of 0
+     * indicates there is no delay constraint. See {@link #hasTimingDelayConstraint()}.
+     */
+    private final long earliestRunTimeElapsedMillis;
+    /**
+     * Latest point in the future at which this job must be run. A value of {@link Long#MAX_VALUE}
+     * indicates there is no deadline constraint. See {@link #hasDeadlineConstraint()}.
+     */
+    private final long latestRunTimeElapsedMillis;
+
+    /** How many times this job has failed, used to compute back-off. */
+    private final int numFailures;
+
     // Constraints.
-    final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean deadlineConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean idleConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean unmeteredConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean connectivityConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean appNotIdleConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean contentTriggerConstraintSatisfied = new AtomicBoolean();
+    final int requiredConstraints;
+    int satisfiedConstraints = 0;
 
     // These are filled in by controllers when preparing for execution.
     public ArraySet<Uri> changedUris;
@@ -76,31 +93,18 @@
      */
     ContentObserverController.JobInstance contentObserverJobInstance;
 
-    /**
-     * Earliest point in the future at which this job will be eligible to run. A value of 0
-     * indicates there is no delay constraint. See {@link #hasTimingDelayConstraint()}.
-     */
-    private long earliestRunTimeElapsedMillis;
-    /**
-     * Latest point in the future at which this job must be run. A value of {@link Long#MAX_VALUE}
-     * indicates there is no deadline constraint. See {@link #hasDeadlineConstraint()}.
-     */
-    private long latestRunTimeElapsedMillis;
-    /** How many times this job has failed, used to compute back-off. */
-    private final int numFailures;
-
     /** Provide a handle to the service that this job will be run on. */
     public int getServiceToken() {
         return callingUid;
     }
 
-    private JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId,
-                      int numFailures) {
+    private JobStatus(JobInfo job, int callingUid, String sourcePackageName,
+            int sourceUserId, int numFailures, long earliestRunTimeElapsedMillis,
+            long latestRunTimeElapsedMillis) {
         this.job = job;
         this.callingUid = callingUid;
         this.name = job.getService().flattenToShortString();
         this.tag = "*job*/" + this.name;
-        this.numFailures = numFailures;
 
         int tempSourceUid = -1;
         if (sourceUserId != -1 && sourcePackageName != null) {
@@ -120,38 +124,42 @@
             this.sourceUserId = sourceUserId;
             this.sourcePackageName = sourcePackageName;
         }
+
+        this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
+        this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
+        this.numFailures = numFailures;
+
+        int requiredConstraints = 0;
+        if (job.getNetworkType() == JobInfo.NETWORK_TYPE_ANY) {
+            requiredConstraints |= CONSTRAINT_CONNECTIVITY;
+        }
+        if (job.getNetworkType() == JobInfo.NETWORK_TYPE_UNMETERED) {
+            requiredConstraints |= CONSTRAINT_UNMETERED;
+        }
+        if (job.isRequireCharging()) {
+            requiredConstraints |= CONSTRAINT_CHARGING;
+        }
+        if (earliestRunTimeElapsedMillis != NO_EARLIEST_RUNTIME) {
+            requiredConstraints |= CONSTRAINT_TIMING_DELAY;
+        }
+        if (latestRunTimeElapsedMillis != NO_LATEST_RUNTIME) {
+            requiredConstraints |= CONSTRAINT_DEADLINE;
+        }
+        if (job.isRequireDeviceIdle()) {
+            requiredConstraints |= CONSTRAINT_IDLE;
+        }
+        if (job.getTriggerContentUris() != null) {
+            requiredConstraints |= CONSTRAINT_CONTENT_TRIGGER;
+        }
+        this.requiredConstraints = requiredConstraints;
     }
 
     /** Copy constructor. */
     public JobStatus(JobStatus jobStatus) {
-        this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getSourcePackageName(),
-                jobStatus.getSourceUserId(), jobStatus.getNumFailures());
-        this.earliestRunTimeElapsedMillis = jobStatus.getEarliestRunTime();
-        this.latestRunTimeElapsedMillis = jobStatus.getLatestRunTimeElapsed();
-    }
-
-    /**
-     * Create a newly scheduled job.
-     * @param callingUid Uid of the package that scheduled this job.
-     * @param sourcePackageName Package name on whose behalf this job is scheduled. Null indicates
-     *                          the calling package is the source.
-     * @param sourceUserId User id for whom this job is scheduled. -1 indicates this is same as the
-     *                     calling userId.
-     */
-    public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId) {
-        this(job, callingUid, sourcePackageName, sourceUserId, 0);
-
-        final long elapsedNow = SystemClock.elapsedRealtime();
-
-        if (job.isPeriodic()) {
-            latestRunTimeElapsedMillis = elapsedNow + job.getIntervalMillis();
-            earliestRunTimeElapsedMillis = latestRunTimeElapsedMillis - job.getFlexMillis();
-        } else {
-            earliestRunTimeElapsedMillis = job.hasEarlyConstraint() ?
-                    elapsedNow + job.getMinLatencyMillis() : NO_EARLIEST_RUNTIME;
-            latestRunTimeElapsedMillis = job.hasLateConstraint() ?
-                    elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
-        }
+        this(jobStatus.getJob(), jobStatus.getUid(),
+                jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(),
+                jobStatus.getNumFailures(), jobStatus.getEarliestRunTime(),
+                jobStatus.getLatestRunTimeElapsed());
     }
 
     /**
@@ -161,22 +169,43 @@
      * wallclock runtime rather than resetting it on every boot.
      * We consider a freshly loaded job to no longer be in back-off.
      */
-    public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId,
-                     long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) {
-        this(job, callingUid, sourcePackageName, sourceUserId, 0);
-
-        this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
-        this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
+    public JobStatus(JobInfo job, int callingUid, String sourcePackageName,
+            int sourceUserId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) {
+        this(job, callingUid, sourcePackageName, sourceUserId, 0, earliestRunTimeElapsedMillis,
+                latestRunTimeElapsedMillis);
     }
 
     /** Create a new job to be rescheduled with the provided parameters. */
     public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis,
                       long newLatestRuntimeElapsedMillis, int backoffAttempt) {
-        this(rescheduling.job, rescheduling.getUid(), rescheduling.getSourcePackageName(),
-                rescheduling.getSourceUserId(), backoffAttempt);
+        this(rescheduling.job, rescheduling.getUid(),
+                rescheduling.getSourcePackageName(),
+                rescheduling.getSourceUserId(), backoffAttempt, newEarliestRuntimeElapsedMillis,
+                newLatestRuntimeElapsedMillis);
+    }
 
-        earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
-        latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
+    /**
+     * Create a newly scheduled job.
+     * @param callingUid Uid of the package that scheduled this job.
+     * @param sourcePackageName Package name on whose behalf this job is scheduled. Null indicates
+     *                          the calling package is the source.
+     * @param sourceUserId User id for whom this job is scheduled. -1 indicates this is same as the
+     */
+    public static JobStatus createFromJobInfo(JobInfo job, int callingUid, String sourcePackageName,
+            int sourceUserId) {
+        final long elapsedNow = SystemClock.elapsedRealtime();
+        final long earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis;
+        if (job.isPeriodic()) {
+            latestRunTimeElapsedMillis = elapsedNow + job.getIntervalMillis();
+            earliestRunTimeElapsedMillis = latestRunTimeElapsedMillis - job.getFlexMillis();
+        } else {
+            earliestRunTimeElapsedMillis = job.hasEarlyConstraint() ?
+                    elapsedNow + job.getMinLatencyMillis() : NO_EARLIEST_RUNTIME;
+            latestRunTimeElapsedMillis = job.hasLateConstraint() ?
+                    elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
+        }
+        return new JobStatus(job, callingUid, sourcePackageName, sourceUserId, 0,
+                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis);
     }
 
     public JobInfo getJob() {
@@ -232,31 +261,31 @@
     }
 
     public boolean hasConnectivityConstraint() {
-        return job.getNetworkType() == JobInfo.NETWORK_TYPE_ANY;
+        return (requiredConstraints&CONSTRAINT_CONNECTIVITY) != 0;
     }
 
     public boolean hasUnmeteredConstraint() {
-        return job.getNetworkType() == JobInfo.NETWORK_TYPE_UNMETERED;
+        return (requiredConstraints&CONSTRAINT_UNMETERED) != 0;
     }
 
     public boolean hasChargingConstraint() {
-        return job.isRequireCharging();
+        return (requiredConstraints&CONSTRAINT_CHARGING) != 0;
     }
 
     public boolean hasTimingDelayConstraint() {
-        return earliestRunTimeElapsedMillis != NO_EARLIEST_RUNTIME;
+        return (requiredConstraints&CONSTRAINT_TIMING_DELAY) != 0;
     }
 
     public boolean hasDeadlineConstraint() {
-        return latestRunTimeElapsedMillis != NO_LATEST_RUNTIME;
+        return (requiredConstraints&CONSTRAINT_DEADLINE) != 0;
     }
 
     public boolean hasIdleConstraint() {
-        return job.isRequireDeviceIdle();
+        return (requiredConstraints&CONSTRAINT_IDLE) != 0;
     }
 
     public boolean hasContentTriggerConstraint() {
-        return job.getTriggerContentUris() != null;
+        return (requiredConstraints&CONSTRAINT_CONTENT_TRIGGER) != 0;
     }
 
     public boolean isPersisted() {
@@ -271,31 +300,74 @@
         return latestRunTimeElapsedMillis;
     }
 
+    boolean setChargingConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_CHARGING, state);
+    }
+
+    boolean setTimingDelayConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_TIMING_DELAY, state);
+    }
+
+    boolean setDeadlineConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_DEADLINE, state);
+    }
+
+    boolean setIdleConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_IDLE, state);
+    }
+
+    boolean setUnmeteredConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_UNMETERED, state);
+    }
+
+    boolean setConnectivityConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_CONNECTIVITY, state);
+    }
+
+    boolean setAppNotIdleConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_APP_NOT_IDLE, state);
+    }
+
+    boolean setContentTriggerConstraintSatisfied(boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_CONTENT_TRIGGER, state);
+    }
+
+    boolean setConstraintSatisfied(int constraint, boolean state) {
+        boolean old = (satisfiedConstraints&constraint) != 0;
+        if (old == state) {
+            return false;
+        }
+        satisfiedConstraints = (satisfiedConstraints&~constraint) | (state ? constraint : 0);
+        return true;
+    }
+
     /**
      * @return Whether or not this job is ready to run, based on its requirements. This is true if
      * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
      */
-    public synchronized boolean isReady() {
+    public boolean isReady() {
         // Deadline constraint trumps other constraints (except for periodic jobs where deadline
         // (is an implementation detail. A periodic job should only run if it's constraints are
         // satisfied).
         // AppNotIdle implicit constraint trumps all!
         return (isConstraintsSatisfied()
-                    || (!job.isPeriodic()
-                            && hasDeadlineConstraint() && deadlineConstraintSatisfied.get()))
-                && appNotIdleConstraintSatisfied.get();
+                || (!job.isPeriodic()
+                && hasDeadlineConstraint() && (satisfiedConstraints&CONSTRAINT_DEADLINE) != 0))
+                && (satisfiedConstraints&CONSTRAINT_APP_NOT_IDLE) != 0;
     }
 
+    static final int CONSTRAINTS_OF_INTEREST =
+            CONSTRAINT_CHARGING | CONSTRAINT_TIMING_DELAY |
+            CONSTRAINT_CONNECTIVITY | CONSTRAINT_UNMETERED |
+            CONSTRAINT_IDLE | CONSTRAINT_CONTENT_TRIGGER;
+
     /**
      * @return Whether the constraints set on this job are satisfied.
      */
-    public synchronized boolean isConstraintsSatisfied() {
-        return (!hasChargingConstraint() || chargingConstraintSatisfied.get())
-                && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
-                && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
-                && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
-                && (!hasIdleConstraint() || idleConstraintSatisfied.get())
-                && (!hasContentTriggerConstraint() || contentTriggerConstraintSatisfied.get());
+    public boolean isConstraintsSatisfied() {
+        final int req = requiredConstraints & CONSTRAINTS_OF_INTEREST;
+        final int sat = satisfiedConstraints & CONSTRAINTS_OF_INTEREST;
+        return (sat & req) == req;
     }
 
     public boolean matches(int uid, int jobId) {
@@ -314,7 +386,7 @@
                 + ",I=" + job.isRequireDeviceIdle()
                 + ",U=" + (job.getTriggerContentUris() != null)
                 + ",F=" + numFailures + ",P=" + job.isPersisted()
-                + ",ANI=" + appNotIdleConstraintSatisfied.get()
+                + ",ANI=" + ((satisfiedConstraints&CONSTRAINT_APP_NOT_IDLE) != 0)
                 + (isReady() ? "(READY)" : "")
                 + "]";
     }
@@ -349,6 +421,33 @@
         return sb.toString();
     }
 
+    void dumpConstraints(PrintWriter pw, int constraints) {
+        if ((constraints&CONSTRAINT_CHARGING) != 0) {
+            pw.print(" CHARGING");
+        }
+        if ((constraints&CONSTRAINT_TIMING_DELAY) != 0) {
+            pw.print(" TIMING_DELAY");
+        }
+        if ((constraints&CONSTRAINT_DEADLINE) != 0) {
+            pw.print(" DEADLINE");
+        }
+        if ((constraints&CONSTRAINT_IDLE) != 0) {
+            pw.print(" IDLE");
+        }
+        if ((constraints&CONSTRAINT_UNMETERED) != 0) {
+            pw.print(" UNMETERED");
+        }
+        if ((constraints&CONSTRAINT_CONNECTIVITY) != 0) {
+            pw.print(" CONNECTIVITY");
+        }
+        if ((constraints&CONSTRAINT_APP_NOT_IDLE) != 0) {
+            pw.print(" APP_NOT_IDLE");
+        }
+        if ((constraints&CONSTRAINT_CONTENT_TRIGGER) != 0) {
+            pw.print(" CONTENT_TRIGGER");
+        }
+    }
+
     // Dumpsys infrastructure
     public void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); UserHandle.formatUid(pw, callingUid);
@@ -413,39 +512,12 @@
         if (job.hasLateConstraint()) {
             pw.print(prefix); pw.println("  Has late constraint");
         }
-        pw.print(prefix); pw.println("Constraints:");
-        if (hasChargingConstraint()) {
-            pw.print(prefix); pw.print("  Charging: ");
-            pw.println(chargingConstraintSatisfied.get());
-        }
-        if (hasTimingDelayConstraint()) {
-            pw.print(prefix); pw.print("  Time delay: ");
-            pw.println(timeDelayConstraintSatisfied.get());
-        }
-        if (hasDeadlineConstraint()) {
-            pw.print(prefix); pw.print("  Deadline: ");
-            pw.println(deadlineConstraintSatisfied.get());
-        }
-        if (hasIdleConstraint()) {
-            pw.print(prefix); pw.print("  System idle: ");
-            pw.println(idleConstraintSatisfied.get());
-        }
-        if (hasUnmeteredConstraint()) {
-            pw.print(prefix); pw.print("  Unmetered: ");
-            pw.println(unmeteredConstraintSatisfied.get());
-        }
-        if (hasConnectivityConstraint()) {
-            pw.print(prefix); pw.print("  Connectivity: ");
-            pw.println(connectivityConstraintSatisfied.get());
-        }
-        if (hasIdleConstraint()) {
-            pw.print(prefix); pw.print("  App not idle: ");
-            pw.println(appNotIdleConstraintSatisfied.get());
-        }
-        if (hasContentTriggerConstraint()) {
-            pw.print(prefix); pw.print("  Content trigger: ");
-            pw.println(contentTriggerConstraintSatisfied.get());
-        }
+        pw.print(prefix); pw.print("Required constraints:");
+        dumpConstraints(pw, requiredConstraints);
+        pw.println();
+        pw.print(prefix); pw.print("Satisfied constraints:");
+        dumpConstraints(pw, satisfiedConstraints);
+        pw.println();
         if (changedAuthorities != null) {
             pw.print(prefix); pw.println("Changed authorities:");
             for (int i=0; i<changedAuthorities.size(); i++) {
diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
index b619ea8..7882bc4d 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -30,13 +30,16 @@
  */
 public abstract class StateController {
     protected static final boolean DEBUG = JobSchedulerService.DEBUG;
-    protected Context mContext;
-    protected StateChangedListener mStateChangedListener;
+    protected final Context mContext;
+    protected final Object mLock;
+    protected final StateChangedListener mStateChangedListener;
     protected boolean mDeviceIdleMode;
 
-    public StateController(StateChangedListener stateChangedListener, Context context) {
+    public StateController(StateChangedListener stateChangedListener, Context context,
+            Object lock) {
         mStateChangedListener = stateChangedListener;
         mContext = context;
+        mLock = lock;
     }
 
     public void deviceIdleModeChanged(boolean enabled) {
@@ -49,21 +52,21 @@
      * Also called when updating a task, so implementing controllers have to be aware of
      * preexisting tasks.
      */
-    public abstract void maybeStartTrackingJob(JobStatus jobStatus, JobStatus lastJob);
+    public abstract void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob);
     /**
      * Optionally implement logic here to prepare the job to be executed.
      */
-    public void prepareForExecution(JobStatus jobStatus) {
+    public void prepareForExecutionLocked(JobStatus jobStatus) {
     }
     /**
      * Remove task - this will happen if the task is cancelled, completed, etc.
      */
-    public abstract void maybeStopTrackingJob(JobStatus jobStatus, boolean forUpdate);
+    public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, boolean forUpdate);
     /**
      * Called when a new job is being created to reschedule an old failed job.
      */
     public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
     }
 
-    public abstract void dumpControllerState(PrintWriter pw);
+    public abstract void dumpControllerStateLocked(PrintWriter pw);
 }
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index a68c3ad..620800c 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -54,13 +54,14 @@
 
     public static synchronized TimeController get(JobSchedulerService jms) {
         if (mSingleton == null) {
-            mSingleton = new TimeController(jms, jms.getContext());
+            mSingleton = new TimeController(jms, jms.getContext(), jms.getLock());
         }
         return mSingleton;
     }
 
-    private TimeController(StateChangedListener stateChangedListener, Context context) {
-        super(stateChangedListener, context);
+    private TimeController(StateChangedListener stateChangedListener, Context context,
+                Object lock) {
+        super(stateChangedListener, context, lock);
 
         mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
@@ -71,9 +72,9 @@
      * list.
      */
     @Override
-    public synchronized void maybeStartTrackingJob(JobStatus job, JobStatus lastJob) {
+    public void maybeStartTrackingJobLocked(JobStatus job, JobStatus lastJob) {
         if (job.hasTimingDelayConstraint() || job.hasDeadlineConstraint()) {
-            maybeStopTrackingJob(job, false);
+            maybeStopTrackingJobLocked(job, false);
             boolean isInsert = false;
             ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
             while (it.hasPrevious()) {
@@ -84,12 +85,11 @@
                     break;
                 }
             }
-            if(isInsert)
-            {
+            if (isInsert) {
                 it.next();
             }
             it.add(job);
-            maybeUpdateAlarms(
+            maybeUpdateAlarmsLocked(
                     job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE,
                     job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE);
         }
@@ -101,7 +101,7 @@
      * Really an == comparison should be enough, but why play with fate? We'll do <=.
      */
     @Override
-    public synchronized void maybeStopTrackingJob(JobStatus job, boolean forUpdate) {
+    public void maybeStopTrackingJobLocked(JobStatus job, boolean forUpdate) {
         if (mTrackedJobs.remove(job)) {
             checkExpiredDelaysAndResetAlarm();
             checkExpiredDeadlinesAndResetAlarm();
@@ -114,14 +114,14 @@
      * the job's deadline is fulfilled - unlike other controllers a time constraint can't toggle
      * back and forth.
      */
-    private boolean canStopTrackingJob(JobStatus job) {
+    private boolean canStopTrackingJobLocked(JobStatus job) {
         return (!job.hasTimingDelayConstraint() ||
-                job.timeDelayConstraintSatisfied.get()) &&
+                (job.satisfiedConstraints&JobStatus.CONSTRAINT_TIMING_DELAY) != 0) &&
                 (!job.hasDeadlineConstraint() ||
-                        job.deadlineConstraintSatisfied.get());
+                        (job.satisfiedConstraints&JobStatus.CONSTRAINT_DEADLINE) != 0);
     }
 
-    private void ensureAlarmService() {
+    private void ensureAlarmServiceLocked() {
         if (mAlarmService == null) {
             mAlarmService = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         }
@@ -131,71 +131,75 @@
      * Checks list of jobs for ones that have an expired deadline, sending them to the JobScheduler
      * if so, removing them from this list, and updating the alarm for the next expiry time.
      */
-    private synchronized void checkExpiredDeadlinesAndResetAlarm() {
-        long nextExpiryTime = Long.MAX_VALUE;
-        final long nowElapsedMillis = SystemClock.elapsedRealtime();
+    private void checkExpiredDeadlinesAndResetAlarm() {
+        synchronized (mLock) {
+            long nextExpiryTime = Long.MAX_VALUE;
+            final long nowElapsedMillis = SystemClock.elapsedRealtime();
 
-        Iterator<JobStatus> it = mTrackedJobs.iterator();
-        while (it.hasNext()) {
-            JobStatus job = it.next();
-            if (!job.hasDeadlineConstraint()) {
-                continue;
-            }
-            final long jobDeadline = job.getLatestRunTimeElapsed();
+            Iterator<JobStatus> it = mTrackedJobs.iterator();
+            while (it.hasNext()) {
+                JobStatus job = it.next();
+                if (!job.hasDeadlineConstraint()) {
+                    continue;
+                }
+                final long jobDeadline = job.getLatestRunTimeElapsed();
 
-            if (jobDeadline <= nowElapsedMillis) {
-                job.deadlineConstraintSatisfied.set(true);
-                mStateChangedListener.onRunJobNow(job);
-                it.remove();
-            } else {  // Sorted by expiry time, so take the next one and stop.
-                nextExpiryTime = jobDeadline;
-                break;
+                if (jobDeadline <= nowElapsedMillis) {
+                    job.setDeadlineConstraintSatisfied(true);
+                    mStateChangedListener.onRunJobNow(job);
+                    it.remove();
+                } else {  // Sorted by expiry time, so take the next one and stop.
+                    nextExpiryTime = jobDeadline;
+                    break;
+                }
             }
+            setDeadlineExpiredAlarmLocked(nextExpiryTime);
         }
-        setDeadlineExpiredAlarm(nextExpiryTime);
     }
 
     /**
      * Handles alarm that notifies us that a job's delay has expired. Iterates through the list of
      * tracked jobs and marks them as ready as appropriate.
      */
-    private synchronized void checkExpiredDelaysAndResetAlarm() {
-        final long nowElapsedMillis = SystemClock.elapsedRealtime();
-        long nextDelayTime = Long.MAX_VALUE;
-        boolean ready = false;
-        Iterator<JobStatus> it = mTrackedJobs.iterator();
-        while (it.hasNext()) {
-            final JobStatus job = it.next();
-            if (!job.hasTimingDelayConstraint()) {
-                continue;
-            }
-            final long jobDelayTime = job.getEarliestRunTime();
-            if (jobDelayTime <= nowElapsedMillis) {
-                job.timeDelayConstraintSatisfied.set(true);
-                if (canStopTrackingJob(job)) {
-                    it.remove();
+    private void checkExpiredDelaysAndResetAlarm() {
+        synchronized (mLock) {
+            final long nowElapsedMillis = SystemClock.elapsedRealtime();
+            long nextDelayTime = Long.MAX_VALUE;
+            boolean ready = false;
+            Iterator<JobStatus> it = mTrackedJobs.iterator();
+            while (it.hasNext()) {
+                final JobStatus job = it.next();
+                if (!job.hasTimingDelayConstraint()) {
+                    continue;
                 }
-                if (job.isReady()) {
-                    ready = true;
-                }
-            } else {  // Keep going through list to get next delay time.
-                if (nextDelayTime > jobDelayTime) {
-                    nextDelayTime = jobDelayTime;
+                final long jobDelayTime = job.getEarliestRunTime();
+                if (jobDelayTime <= nowElapsedMillis) {
+                    job.setTimingDelayConstraintSatisfied(true);
+                    if (canStopTrackingJobLocked(job)) {
+                        it.remove();
+                    }
+                    if (job.isReady()) {
+                        ready = true;
+                    }
+                } else {  // Keep going through list to get next delay time.
+                    if (nextDelayTime > jobDelayTime) {
+                        nextDelayTime = jobDelayTime;
+                    }
                 }
             }
+            if (ready) {
+                mStateChangedListener.onControllerStateChanged();
+            }
+            setDelayExpiredAlarmLocked(nextDelayTime);
         }
-        if (ready) {
-            mStateChangedListener.onControllerStateChanged();
-        }
-        setDelayExpiredAlarm(nextDelayTime);
     }
 
-    private void maybeUpdateAlarms(long delayExpiredElapsed, long deadlineExpiredElapsed) {
+    private void maybeUpdateAlarmsLocked(long delayExpiredElapsed, long deadlineExpiredElapsed) {
         if (delayExpiredElapsed < mNextDelayExpiredElapsedMillis) {
-            setDelayExpiredAlarm(delayExpiredElapsed);
+            setDelayExpiredAlarmLocked(delayExpiredElapsed);
         }
         if (deadlineExpiredElapsed < mNextJobExpiredElapsedMillis) {
-            setDeadlineExpiredAlarm(deadlineExpiredElapsed);
+            setDeadlineExpiredAlarmLocked(deadlineExpiredElapsed);
         }
     }
 
@@ -204,10 +208,11 @@
      * delay will expire.
      * This alarm <b>will</b> wake up the phone.
      */
-    private void setDelayExpiredAlarm(long alarmTimeElapsedMillis) {
+    private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis) {
         alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
         mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
-        updateAlarmWithListener(DELAY_TAG, mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis);
+        updateAlarmWithListenerLocked(DELAY_TAG, mNextDelayExpiredListener,
+                mNextDelayExpiredElapsedMillis);
     }
 
     /**
@@ -215,10 +220,11 @@
      * deadline will expire.
      * This alarm <b>will</b> wake up the phone.
      */
-    private void setDeadlineExpiredAlarm(long alarmTimeElapsedMillis) {
+    private void setDeadlineExpiredAlarmLocked(long alarmTimeElapsedMillis) {
         alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
         mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis;
-        updateAlarmWithListener(DEADLINE_TAG, mDeadlineExpiredListener, mNextJobExpiredElapsedMillis);
+        updateAlarmWithListenerLocked(DEADLINE_TAG, mDeadlineExpiredListener,
+                mNextJobExpiredElapsedMillis);
     }
 
     private long maybeAdjustAlarmTime(long proposedAlarmTimeElapsedMillis) {
@@ -229,9 +235,9 @@
         return proposedAlarmTimeElapsedMillis;
     }
 
-    private void updateAlarmWithListener(String tag, OnAlarmListener listener,
+    private void updateAlarmWithListenerLocked(String tag, OnAlarmListener listener,
             long alarmTimeElapsed) {
-        ensureAlarmService();
+        ensureAlarmServiceLocked();
         if (alarmTimeElapsed == Long.MAX_VALUE) {
             mAlarmService.cancel(listener);
         } else {
@@ -266,7 +272,7 @@
     };
 
     @Override
-    public void dumpControllerState(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw) {
         final long nowElapsed = SystemClock.elapsedRealtime();
         pw.println("Alarms (" + SystemClock.elapsedRealtime() + ")");
         pw.println(
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index c1eb844..7fb1783 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1684,25 +1684,25 @@
     /**
      * Called from native code to inform us the hardware information.
      */
-    private void setGpsYearOfHardware(int yearOfHardware) {
-        if (DEBUG) Log.d(TAG, "setGpsYearOfHardware called with " + yearOfHardware);
+    private void setGnssYearOfHardware(int yearOfHardware) {
+        if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
         mYearOfHardware = yearOfHardware;
     }
 
-    public interface GpsSystemInfoProvider {
+    public interface GnssSystemInfoProvider {
         /**
          * Returns the year of GPS hardware.
          */
-        int getGpsYearOfHardware();
+        int getGnssYearOfHardware();
     }
 
     /**
      * @hide
      */
-    public GpsSystemInfoProvider getGpsSystemInfoProvider() {
-        return new GpsSystemInfoProvider() {
+    public GnssSystemInfoProvider getGnssSystemInfoProvider() {
+        return new GnssSystemInfoProvider() {
             @Override
-            public int getGpsYearOfHardware() {
+            public int getGnssYearOfHardware() {
                 return mYearOfHardware;
             }
         };
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 246da2e..862c061 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -868,6 +868,38 @@
             }
         }
 
+        public void prepare() {
+            try {
+                mCb.onPrepare();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in prepare.", e);
+            }
+        }
+
+        public void prepareFromMediaId(String mediaId, Bundle extras) {
+            try {
+                mCb.onPrepareFromMediaId(mediaId, extras);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in prepareFromMediaId.", e);
+            }
+        }
+
+        public void prepareFromSearch(String query, Bundle extras) {
+            try {
+                mCb.onPrepareFromSearch(query, extras);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in prepareFromSearch.", e);
+            }
+        }
+
+        public void prepareFromUri(Uri uri, Bundle extras) {
+            try {
+                mCb.onPrepareFromUri(uri, extras);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in prepareFromUri.", e);
+            }
+        }
+
         public void play() {
             try {
                 mCb.onPlay();
@@ -880,7 +912,7 @@
             try {
                 mCb.onPlayFromMediaId(mediaId, extras);
             } catch (RemoteException e) {
-                Slog.e(TAG, "Remote failure in playUri.", e);
+                Slog.e(TAG, "Remote failure in playFromMediaId.", e);
             }
         }
 
@@ -1100,6 +1132,27 @@
         }
 
         @Override
+        public void prepare() throws RemoteException {
+            mSessionCb.prepare();
+        }
+
+        @Override
+        public void prepareFromMediaId(String mediaId, Bundle extras)
+                throws RemoteException {
+            mSessionCb.prepareFromMediaId(mediaId, extras);
+        }
+
+        @Override
+        public void prepareFromSearch(String query, Bundle extras) throws RemoteException {
+            mSessionCb.prepareFromSearch(query, extras);
+        }
+
+        @Override
+        public void prepareFromUri(Uri uri, Bundle extras) throws RemoteException {
+            mSessionCb.prepareFromUri(uri, extras);
+        }
+
+        @Override
         public void play() throws RemoteException {
             mSessionCb.play();
         }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index bc5b561..3421433 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1742,13 +1742,18 @@
     public void setNetworkPolicies(NetworkPolicy[] policies) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
-        maybeRefreshTrustedTime();
-        synchronized (mRulesLock) {
-            normalizePoliciesLocked(policies);
-            updateNetworkEnabledLocked();
-            updateNetworkRulesLocked();
-            updateNotificationsLocked();
-            writePolicyLocked();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            maybeRefreshTrustedTime();
+            synchronized (mRulesLock) {
+                normalizePoliciesLocked(policies);
+                updateNetworkEnabledLocked();
+                updateNetworkRulesLocked();
+                updateNotificationsLocked();
+                writePolicyLocked();
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
@@ -1851,13 +1856,18 @@
     @Override
     public void setRestrictBackground(boolean restrictBackground) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            maybeRefreshTrustedTime();
+            synchronized (mRulesLock) {
+                mRestrictBackground = restrictBackground;
+                updateRulesForGlobalChangeLocked(true);
+                updateNotificationsLocked();
+                writePolicyLocked();
+            }
 
-        maybeRefreshTrustedTime();
-        synchronized (mRulesLock) {
-            mRestrictBackground = restrictBackground;
-            updateRulesForGlobalChangeLocked(true);
-            updateNotificationsLocked();
-            writePolicyLocked();
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
 
         mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0)
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
index 5cd1025..a5dc008 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
@@ -211,12 +211,7 @@
         if (enabled < 0) {
             return enabled;
         }
-        final long token = Binder.clearCallingIdentity();
-        try {
-            mInterface.setRestrictBackground(enabled > 0);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
+        mInterface.setRestrictBackground(enabled > 0);
         return 0;
     }
 
@@ -225,12 +220,7 @@
       if (uid < 0) {
           return uid;
       }
-      final long token = Binder.clearCallingIdentity();
-      try {
-          mInterface.addRestrictBackgroundWhitelistedUid(uid);
-      } finally {
-          Binder.restoreCallingIdentity(token);
-      }
+      mInterface.addRestrictBackgroundWhitelistedUid(uid);
       return 0;
     }
 
@@ -239,12 +229,7 @@
         if (uid < 0) {
             return uid;
         }
-        final long token = Binder.clearCallingIdentity();
-        try {
-            mInterface.removeRestrictBackgroundWhitelistedUid(uid);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
+        mInterface.removeRestrictBackgroundWhitelistedUid(uid);
         return 0;
     }
 
diff --git a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java b/services/core/java/com/android/server/notification/ImportanceExtractor.java
similarity index 84%
rename from services/core/java/com/android/server/notification/TopicImportanceExtractor.java
rename to services/core/java/com/android/server/notification/ImportanceExtractor.java
index c6b3e0f..885b9b7 100644
--- a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
+++ b/services/core/java/com/android/server/notification/ImportanceExtractor.java
@@ -21,7 +21,7 @@
 /**
  * Determines the importance of the given notification.
  */
-public class TopicImportanceExtractor implements NotificationSignalExtractor {
+public class ImportanceExtractor implements NotificationSignalExtractor {
     private static final String TAG = "ImportantTopicExtractor";
     private static final boolean DBG = false;
 
@@ -42,9 +42,8 @@
             return null;
         }
 
-        final int topicImportance = mConfig.getImportance(record.sbn.getPackageName(),
-                record.sbn.getUid(), record.sbn.getNotification().getTopic());
-        record.setTopicImportance(topicImportance);
+        record.setUserImportance(
+                mConfig.getImportance(record.sbn.getPackageName(), record.sbn.getUid()));
 
         return null;
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ede1a2f..95198a3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -30,7 +30,6 @@
 import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_CHANGED;
 import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_SUSPENDED;
 import static android.service.notification.NotificationAssistantService.REASON_PROFILE_TURNED_OFF;
-import static android.service.notification.NotificationAssistantService.REASON_TOPIC_BANNED;
 import static android.service.notification.NotificationAssistantService.REASON_USER_STOPPED;
 import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
 import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF;
@@ -754,7 +753,7 @@
                     for (String pkgName : pkgList) {
                         if (cancelNotifications) {
                             cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, 0, 0, !queryRestart,
-                                    changeUserId, reason, null, null);
+                                    changeUserId, reason, null);
                         }
                     }
                 }
@@ -787,14 +786,14 @@
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (userHandle >= 0) {
                     cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle,
-                            REASON_USER_STOPPED, null, null);
+                            REASON_USER_STOPPED, null);
                 }
             } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED)) {
                 boolean inQuietMode = intent.getBooleanExtra(Intent.EXTRA_QUIET_MODE, false);
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (inQuietMode && userHandle >= 0) {
                     cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle,
-                            REASON_PROFILE_TURNED_OFF, null, null);
+                            REASON_PROFILE_TURNED_OFF, null);
                 }
             } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                 // turn off LED when user passes through lock screen
@@ -1086,7 +1085,7 @@
         // Now, cancel any outstanding notifications that are part of a just-disabled app
         if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) {
             cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true, UserHandle.getUserId(uid),
-                    REASON_PACKAGE_BANNED, null, null);
+                    REASON_PACKAGE_BANNED, null);
         }
     }
 
@@ -1250,7 +1249,7 @@
             // running foreground services.
             cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
                     pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId,
-                    REASON_APP_CANCEL_ALL, null, null);
+                    REASON_APP_CANCEL_ALL, null);
         }
 
         @Override
@@ -1279,79 +1278,50 @@
         }
 
         @Override
-        public boolean hasBannedTopics(String pkg, int uid) {
+        public void setPriority(String pkg, int uid, int priority) {
             checkCallerIsSystem();
-            return mRankingHelper.hasBannedTopics(pkg, uid);
-        }
-
-        @Override
-        public ParceledListSlice<Notification.Topic> getTopics(String pkg, int uid) {
-            checkCallerIsSystem();
-            return new ParceledListSlice<Notification.Topic>(mRankingHelper.getTopics(pkg, uid));
-        }
-
-        @Override
-        public void setPriority(String pkg, int uid, Notification.Topic topic, int priority) {
-            checkCallerIsSystem();
-            mRankingHelper.setPriority(pkg, uid, topic, priority);
+            mRankingHelper.setPriority(pkg, uid, priority);
             savePolicyFile();
         }
 
         @Override
-        public int getPriority(String pkg, int uid, Notification.Topic topic) {
+        public int getPriority(String pkg, int uid) {
             checkCallerIsSystem();
-            return mRankingHelper.getPriority(pkg, uid, topic);
+            return mRankingHelper.getPriority(pkg, uid);
         }
 
         @Override
-        public void setVisibilityOverride(String pkg, int uid, Notification.Topic topic,
-                int visibility) {
+        public void setVisibilityOverride(String pkg, int uid, int visibility) {
             checkCallerIsSystem();
-            mRankingHelper.setVisibilityOverride(pkg, uid, topic, visibility);
+            mRankingHelper.setVisibilityOverride(pkg, uid, visibility);
             savePolicyFile();
         }
 
         @Override
-        public int getVisibilityOverride(String pkg, int uid, Notification.Topic topic) {
+        public int getVisibilityOverride(String pkg, int uid) {
             checkCallerIsSystem();
-            return mRankingHelper.getVisibilityOverride(pkg, uid, topic);
+            return mRankingHelper.getVisibilityOverride(pkg, uid);
         }
 
         @Override
-        public void setImportance(String pkg, int uid, Notification.Topic topic,
-                int importance) {
+        public void setImportance(String pkg, int uid,  int importance) {
             enforceSystemOrSystemUI("Caller not system or systemui");
-            if (topic == null) {
-                // App wide, potentially store block in app ops.
-                setNotificationsEnabledForPackageImpl(pkg, uid,
-                        importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
-            } else {
-                if (NotificationListenerService.Ranking.IMPORTANCE_NONE == importance) {
-                    cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true,
-                            UserHandle.getUserId(uid),
-                            REASON_TOPIC_BANNED, topic, null);
-                }
-            }
-            mRankingHelper.setImportance(pkg, uid, topic, importance);
+            setNotificationsEnabledForPackageImpl(pkg, uid,
+                    importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
+            mRankingHelper.setImportance(pkg, uid, importance);
             savePolicyFile();
         }
 
         @Override
-        public int getTopicImportance(String pkg, String topicId) {
+        public int getPackageImportance(String pkg) {
             checkCallerIsSystemOrSameApp(pkg);
-            return mRankingHelper.getImportance(pkg, Binder.getCallingUid(), topicId);
+            return mRankingHelper.getImportance(pkg, Binder.getCallingUid());
         }
 
         @Override
-        public int getImportance(String pkg, int uid, Notification.Topic topic) {
+        public int getImportance(String pkg, int uid) {
             checkCallerIsSystem();
-            return mRankingHelper.getImportance(pkg, uid, topic);
-        }
-
-        @Override
-        public boolean doesUserUseTopics(String pkg, int uid) {
-            enforceSystemOrSystemUI("Caller not system or systemui");
-            return mRankingHelper.doesUserUseTopics(pkg, uid);
+            return mRankingHelper.getImportance(pkg, uid);
         }
 
         /**
@@ -2381,11 +2351,9 @@
 
                 mRankingHelper.extractSignals(r);
 
-                // why is this here?
-                savePolicyFile();
                 final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
 
-                // blocked apps/topics
+                // blocked apps
                 if (r.getImportance() == NotificationListenerService.Ranking.IMPORTANCE_NONE
                         || !noteNotificationOp(pkg, callingUid) || isPackageSuspended) {
                     if (!isSystemNotification) {
@@ -3182,11 +3150,11 @@
     }
 
     /**
-     * Cancels all notifications from a given package or topic that have all of the
+     * Cancels all notifications from a given package that have all of the
      * {@code mustHaveFlags}.
      */
     boolean cancelAllNotificationsInt(int callingUid, int callingPid, String pkg, int mustHaveFlags,
-            int mustNotHaveFlags, boolean doit, int userId, int reason, Notification.Topic topic,
+            int mustNotHaveFlags, boolean doit, int userId, int reason,
             ManagedServiceInfo listener) {
         String listenerName = listener == null ? null : listener.component.toShortString();
         EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
@@ -3214,10 +3182,6 @@
                 if (pkg != null && !r.sbn.getPackageName().equals(pkg)) {
                     continue;
                 }
-                if (topic != null
-                        && !topic.getId().equals(r.getNotification().getTopic().getId())) {
-                    continue;
-                }
                 if (canceledNotifications == null) {
                     canceledNotifications = new ArrayList<>();
                 }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 2ca5534..25d17f6 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -35,7 +35,6 @@
 import android.service.notification.StatusBarNotification;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
 import com.android.server.EventLogTags;
 
 import java.io.PrintWriter;
@@ -92,12 +91,12 @@
     private int mAuthoritativeRank;
     private String mGlobalSortKey;
     private int mPackageVisibility;
-    private int mTopicImportance = IMPORTANCE_UNSPECIFIED;
+    private int mUserImportance = IMPORTANCE_UNSPECIFIED;
     private int mImportance = IMPORTANCE_UNSPECIFIED;
     private CharSequence mImportanceExplanation = null;
 
     private int mSuppressedVisualEffects = 0;
-    private String mTopicExplanation;
+    private String mUserExplanation;
     private String mPeopleExplanation;
 
     @VisibleForTesting
@@ -183,7 +182,7 @@
         mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
         mCreationTimeMs = previous.mCreationTimeMs;
         mVisibleSinceMs = previous.mVisibleSinceMs;
-        mTopicImportance = previous.mTopicImportance;
+        mUserImportance = previous.mUserImportance;
         mImportance = previous.mImportance;
         mImportanceExplanation = previous.mImportanceExplanation;
         // Don't copy mGlobalSortKey, recompute it.
@@ -275,8 +274,8 @@
         pw.println(prefix + "  mRecentlyIntrusive=" + mRecentlyIntrusive);
         pw.println(prefix + "  mPackagePriority=" + mPackagePriority);
         pw.println(prefix + "  mPackageVisibility=" + mPackageVisibility);
-        pw.println(prefix + "  mTopicImportance="
-                + NotificationListenerService.Ranking.importanceToString(mTopicImportance));
+        pw.println(prefix + "  mUserImportance="
+                + NotificationListenerService.Ranking.importanceToString(mUserImportance));
         pw.println(prefix + "  mImportance="
                 + NotificationListenerService.Ranking.importanceToString(mImportance));
         pw.println(prefix + "  mImportanceExplanation=" + mImportanceExplanation);
@@ -357,17 +356,17 @@
         return mPackageVisibility;
     }
 
-    public void setTopicImportance(int importance) {
-        mTopicImportance = importance;
-        applyTopicImportance();
+    public void setUserImportance(int importance) {
+        mUserImportance = importance;
+        applyUserImportance();
     }
 
-    private String getTopicExplanation() {
-        if (mTopicExplanation == null) {
-            mTopicExplanation =
-                    mContext.getString(com.android.internal.R.string.importance_from_topic);
+    private String getUserExplanation() {
+        if (mUserExplanation == null) {
+            mUserExplanation =
+                    mContext.getString(com.android.internal.R.string.importance_from_user);
         }
-        return mTopicExplanation;
+        return mUserExplanation;
     }
 
     private String getPeopleExplanation() {
@@ -378,15 +377,15 @@
         return mPeopleExplanation;
     }
 
-    private void applyTopicImportance() {
-        if (mTopicImportance != NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED) {
-            mImportance = mTopicImportance;
-            mImportanceExplanation = getTopicExplanation();
+    private void applyUserImportance() {
+        if (mUserImportance != NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED) {
+            mImportance = mUserImportance;
+            mImportanceExplanation = getUserExplanation();
         }
     }
 
-    public int getTopicImportance() {
-        return mTopicImportance;
+    public int getUserImportance() {
+        return mUserImportance;
     }
 
     public void setImportance(int importance, CharSequence explanation) {
@@ -394,7 +393,7 @@
             mImportance = importance;
             mImportanceExplanation = explanation;
         }
-        applyTopicImportance();
+        applyUserImportance();
     }
 
     public int getImportance() {
@@ -529,6 +528,6 @@
     }
 
     public boolean isImportanceFromUser() {
-        return mImportance == mTopicImportance;
+        return mImportance == mUserImportance;
     }
 }
diff --git a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java b/services/core/java/com/android/server/notification/PriorityExtractor.java
similarity index 84%
rename from services/core/java/com/android/server/notification/TopicPriorityExtractor.java
rename to services/core/java/com/android/server/notification/PriorityExtractor.java
index 1df5c2b..6c76476 100644
--- a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
+++ b/services/core/java/com/android/server/notification/PriorityExtractor.java
@@ -21,7 +21,7 @@
 /**
  * Determines if the given notification can bypass Do Not Disturb.
  */
-public class TopicPriorityExtractor implements NotificationSignalExtractor {
+public class PriorityExtractor implements NotificationSignalExtractor {
     private static final String TAG = "ImportantTopicExtractor";
     private static final boolean DBG = false;
 
@@ -42,9 +42,8 @@
             return null;
         }
 
-        final int packagePriority = mConfig.getPriority(record.sbn.getPackageName(),
-                record.sbn.getUid(), record.sbn.getNotification().getTopic());
-        record.setPackagePriority(packagePriority);
+        record.setPackagePriority(
+                mConfig.getPriority(record.sbn.getPackageName(), record.sbn.getUid()));
 
         return null;
     }
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 9773474..b5cc2ef 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -15,30 +15,17 @@
  */
 package com.android.server.notification;
 
-import android.app.Notification;
-
-import java.util.List;
-
 public interface RankingConfig {
 
-    List<Notification.Topic> getTopics(String packageName, int uid);
+    int getPriority(String packageName, int uid);
 
-    int getPriority(String packageName, int uid, Notification.Topic topic);
+    void setPriority(String packageName, int uid, int priority);
 
-    void setPriority(String packageName, int uid, Notification.Topic topic, int priority);
+    int getVisibilityOverride(String packageName, int uid);
 
-    int getVisibilityOverride(String packageName, int uid, Notification.Topic topic);
+    void setVisibilityOverride(String packageName, int uid, int visibility);
 
-    void setVisibilityOverride(String packageName, int uid, Notification.Topic topic,
-            int visibility);
+    void setImportance(String packageName, int uid, int importance);
 
-    void setImportance(String packageName, int uid, Notification.Topic topic, int importance);
-
-    int getImportance(String packageName, int uid, Notification.Topic topic);
-
-    boolean doesUserUseTopics(String packageName, int uid);
-
-    boolean hasBannedTopics(String packageName, int uid);
-
-    int getImportance(String packageName, int uid, String topicId);
+    int getImportance(String packageName, int uid);
 }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 91eab10..fd96a78 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -20,14 +20,11 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.UserHandle;
-import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Slog;
 
-import com.android.internal.R;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -36,8 +33,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.List;
-import java.util.Map;
 
 public class RankingHelper implements RankingConfig {
     private static final String TAG = "RankingHelper";
@@ -47,7 +42,6 @@
     private static final String TAG_RANKING = "ranking";
     private static final String TAG_PACKAGE = "package";
     private static final String ATT_VERSION = "version";
-    private static final String TAG_TOPIC = "topic";
 
     private static final String ATT_NAME = "name";
     private static final String ATT_UID = "uid";
@@ -141,8 +135,6 @@
             if (type == XmlPullParser.START_TAG) {
                 if (TAG_PACKAGE.equals(tag)) {
                     int uid = safeInt(parser, ATT_UID, Record.UNKNOWN_UID);
-                    int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
-                    int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
                     String name = parser.getAttributeValue(null, ATT_NAME);
 
                     if (!TextUtils.isEmpty(name)) {
@@ -165,16 +157,8 @@
                             r = getOrCreateRecord(name, uid);
                         }
                         r.importance = safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
-                        r.priority = priority;
-                        r.visibility = vis;
-
-                        // Migrate package level settings to the default topic.
-                        // Might be overwritten by parseTopics.
-                        Topic defaultTopic = r.topics.get(Notification.TOPIC_DEFAULT);
-                        defaultTopic.priority = priority;
-                        defaultTopic.visibility = vis;
-
-                        parseTopics(r, parser);
+                        r.priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+                        r.visibility = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
                     }
                 }
             }
@@ -182,42 +166,6 @@
         throw new IllegalStateException("Failed to reach END_DOCUMENT");
     }
 
-    public void parseTopics(Record r, XmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        final int innerDepth = parser.getDepth();
-        int type;
-        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
-            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                continue;
-            }
-
-            String tagName = parser.getName();
-            if (TAG_TOPIC.equals(tagName)) {
-                int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
-                int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
-                int importance = safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
-                String id = parser.getAttributeValue(null, ATT_TOPIC_ID);
-                CharSequence label = parser.getAttributeValue(null, ATT_TOPIC_LABEL);
-
-                if (!TextUtils.isEmpty(id)) {
-                    Topic topic = new Topic(new Notification.Topic(id, label));
-
-                    if (priority != DEFAULT_PRIORITY) {
-                        topic.priority = priority;
-                    }
-                    if (vis != DEFAULT_VISIBILITY) {
-                        topic.visibility = vis;
-                    }
-                    if (importance != DEFAULT_IMPORTANCE) {
-                        topic.importance = importance;
-                    }
-                    r.topics.put(id, topic);
-                }
-            }
-        }
-    }
-
     private static String recordKey(String pkg, int uid) {
         return pkg + "|" + uid;
     }
@@ -229,7 +177,6 @@
             r = new Record();
             r.pkg = pkg;
             r.uid = uid;
-            r.topics.put(Notification.TOPIC_DEFAULT, new Topic(createDefaultTopic()));
             mRecords.put(key, r);
         }
         return r;
@@ -246,46 +193,31 @@
             if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
                 continue;
             }
-            out.startTag(null, TAG_PACKAGE);
-            out.attribute(null, ATT_NAME, r.pkg);
-            if (r.importance != DEFAULT_IMPORTANCE) {
-                out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
-            }
-            if (r.priority != DEFAULT_PRIORITY) {
-                out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
-            }
-            if (r.visibility != DEFAULT_VISIBILITY) {
-                out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
-            }
+            final boolean hasNonDefaultSettings = r.importance != DEFAULT_IMPORTANCE
+                    || r.priority != DEFAULT_PRIORITY || r.visibility != DEFAULT_VISIBILITY;
+            if (hasNonDefaultSettings) {
+                out.startTag(null, TAG_PACKAGE);
+                out.attribute(null, ATT_NAME, r.pkg);
+                if (r.importance != DEFAULT_IMPORTANCE) {
+                    out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
+                }
+                if (r.priority != DEFAULT_PRIORITY) {
+                    out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
+                }
+                if (r.visibility != DEFAULT_VISIBILITY) {
+                    out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
+                }
 
-            if (!forBackup) {
-                out.attribute(null, ATT_UID, Integer.toString(r.uid));
-            }
+                if (!forBackup) {
+                    out.attribute(null, ATT_UID, Integer.toString(r.uid));
+                }
 
-            writeTopicsXml(out, r);
-            out.endTag(null, TAG_PACKAGE);
+                out.endTag(null, TAG_PACKAGE);
+            }
         }
         out.endTag(null, TAG_RANKING);
     }
 
-    public void writeTopicsXml(XmlSerializer out, Record r) throws IOException {
-        for (Topic t : r.topics.values()) {
-            out.startTag(null, TAG_TOPIC);
-            out.attribute(null, ATT_TOPIC_ID, t.topic.getId());
-            out.attribute(null, ATT_TOPIC_LABEL, t.topic.getLabel().toString());
-            if (t.priority != DEFAULT_PRIORITY) {
-                out.attribute(null, ATT_PRIORITY, Integer.toString(t.priority));
-            }
-            if (t.visibility != DEFAULT_VISIBILITY) {
-                out.attribute(null, ATT_VISIBILITY, Integer.toString(t.visibility));
-            }
-            if (t.importance != DEFAULT_IMPORTANCE) {
-                out.attribute(null, ATT_IMPORTANCE, Integer.toString(t.importance));
-            }
-            out.endTag(null, TAG_TOPIC);
-        }
-    }
-
     private void updateConfig() {
         final int N = mSignalExtractors.length;
         for (int i = 0; i < N; i++) {
@@ -370,189 +302,62 @@
         }
     }
 
-    private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
-        final String val = parser.getAttributeValue(null, att);
-        return tryParseBool(val, defValue);
-    }
-
     private static boolean tryParseBool(String value, boolean defValue) {
         if (TextUtils.isEmpty(value)) return defValue;
         return Boolean.valueOf(value);
     }
 
+    /**
+     * Gets priority.
+     */
     @Override
-    public List<Notification.Topic> getTopics(String packageName, int uid) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        List<Notification.Topic> topics = new ArrayList<>();
-        for (Topic t : r.topics.values()) {
-            topics.add(t.topic);
-        }
-        return topics;
-    }
-
-    @Override
-    public boolean hasBannedTopics(String packageName, int uid) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        for (Topic t : r.topics.values()) {
-            if (t.importance == Ranking.IMPORTANCE_NONE) {
-                return true;
-            }
-        }
-        return false;
+    public int getPriority(String packageName, int uid) {
+        return getOrCreateRecord(packageName, uid).priority;
     }
 
     /**
-     * Gets priority. If a topic is given, returns the priority of that topic. Otherwise, the
-     * priority of the app.
+     * Sets priority.
      */
     @Override
-    public int getPriority(String packageName, int uid, Notification.Topic topic) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        if (topic == null) {
-            return r.priority;
-        }
-        return getOrCreateTopic(r, topic).priority;
-    }
-
-    /**
-     * Sets priority. If a topic is given, sets the priority of that topic. If not,
-     * sets the default priority for all new topics that appear in the future, and resets
-     * the priority of all current topics.
-     */
-    @Override
-    public void setPriority(String packageName, int uid, Notification.Topic topic,
-            int priority) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        if (topic == null) {
-            r.priority = priority;
-            for (Topic t : r.topics.values()) {
-                t.priority = priority;
-            }
-        } else {
-            getOrCreateTopic(r, topic).priority = priority;
-        }
+    public void setPriority(String packageName, int uid, int priority) {
+        getOrCreateRecord(packageName, uid).priority = priority;
         updateConfig();
     }
 
     /**
-     * Gets visual override. If a topic is given, returns the override of that topic. Otherwise, the
-     * override of the app.
+     * Gets visual override.
      */
     @Override
-    public int getVisibilityOverride(String packageName, int uid, Notification.Topic topic) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        if (topic == null) {
-            return r.visibility;
-        }
-        return getOrCreateTopic(r, topic).visibility;
+    public int getVisibilityOverride(String packageName, int uid) {
+        return getOrCreateRecord(packageName, uid).visibility;
     }
 
     /**
-     * Sets visibility override. If a topic is given, sets the override of that topic. If not,
-     * sets the default override for all new topics that appear in the future, and resets
-     * the override of all current topics.
+     * Sets visibility override.
      */
     @Override
-    public void setVisibilityOverride(String pkgName, int uid, Notification.Topic topic,
-        int visibility) {
-        final Record r = getOrCreateRecord(pkgName, uid);
-        if (topic == null) {
-            r.visibility = visibility;
-            for (Topic t : r.topics.values()) {
-                t.visibility = visibility;
-            }
-        } else {
-            getOrCreateTopic(r, topic).visibility = visibility;
-        }
+    public void setVisibilityOverride(String pkgName, int uid, int visibility) {
+        getOrCreateRecord(pkgName, uid).visibility = visibility;
         updateConfig();
     }
 
     /**
-     * Gets the importance of a topic. Unlike {@link #getImportance(String, int, String)}, does not
-     * create package or topic records if they don't exist.
+     * Gets importance.
      */
     @Override
-    public int getImportance(String packageName, int uid, String topicId) {
-        final String key = recordKey(packageName, uid);
-        Record r = mRecords.get(key);
-        if (r == null) {
-            return Ranking.IMPORTANCE_UNSPECIFIED;
-        }
-        Topic t = r.topics.get(topicId);
-        if (t == null) {
-            return Ranking.IMPORTANCE_UNSPECIFIED;
-        }
-        return t.importance;
+    public int getImportance(String packageName, int uid) {
+        return getOrCreateRecord(packageName, uid).importance;
     }
 
     /**
-     * Gets importance. If a topic is given, returns the importance of that topic. Otherwise, the
-     * importance of the app.
+     * Sets importance.
      */
     @Override
-    public int getImportance(String packageName, int uid, Notification.Topic topic) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        if (topic == null) {
-            return r.importance;
-        }
-        return getOrCreateTopic(r, topic).importance;
-    }
-
-    /**
-     * Sets importance. If a topic is given, sets the importance of that topic. If not, sets the
-     * default importance for all new topics that appear in the future, and resets
-     * the importance of all current topics (unless the app is being blocked).
-     */
-    @Override
-    public void setImportance(String pkgName, int uid, Notification.Topic topic,
-            int importance) {
-        final Record r = getOrCreateRecord(pkgName, uid);
-        if (topic == null) {
-            r.importance = importance;
-            if (Ranking.IMPORTANCE_NONE != importance) {
-                for (Topic t : r.topics.values()) {
-                    t.importance = importance;
-                }
-            }
-        } else {
-            getOrCreateTopic(r, topic).importance = importance;
-        }
+    public void setImportance(String pkgName, int uid, int importance) {
+        getOrCreateRecord(pkgName, uid).importance = importance;
         updateConfig();
     }
 
-    @Override
-    public boolean doesUserUseTopics(String pkgName, int uid) {
-        final Record r = getOrCreateRecord(pkgName, uid);
-        for (Topic topic : r.topics.values()) {
-            if (topic.importance != Ranking.IMPORTANCE_UNSPECIFIED
-                    && r.importance != topic.importance)
-                return true;
-        }
-        return false;
-    }
-
-    private Topic getOrCreateTopic(Record r, Notification.Topic topic) {
-        if (topic == null) {
-            topic = createDefaultTopic();
-        }
-        Topic t = r.topics.get(topic.getId());
-        if (t != null) {
-            return t;
-        } else {
-            t = new Topic(topic);
-            t.importance = r.importance;
-            t.priority = r.priority;
-            t.visibility = r.visibility;
-            r.topics.put(topic.getId(), t);
-            return t;
-        }
-    }
-
-    private Notification.Topic createDefaultTopic() {
-        return new Notification.Topic(Notification.TOPIC_DEFAULT,
-                mContext.getString(R.string.default_notification_topic_label));
-    }
-
     public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
         if (filter == null) {
             final int N = mSignalExtractors.length;
@@ -600,25 +405,6 @@
                     pw.print(Ranking.importanceToString(r.visibility));
                 }
                 pw.println();
-                for (Topic t : r.topics.values()) {
-                    pw.print(prefix);
-                    pw.print("  ");
-                    pw.print("  ");
-                    pw.print(t.topic.getId());
-                    if (t.priority != DEFAULT_PRIORITY) {
-                        pw.print(" priority=");
-                        pw.print(Notification.priorityToString(t.priority));
-                    }
-                    if (t.visibility != DEFAULT_VISIBILITY) {
-                        pw.print(" visibility=");
-                        pw.print(Notification.visibilityToString(t.visibility));
-                    }
-                    if (t.importance != DEFAULT_IMPORTANCE) {
-                        pw.print(" importance=");
-                        pw.print(Ranking.importanceToString(t.importance));
-                    }
-                    pw.println();
-                }
             }
         }
     }
@@ -657,17 +443,5 @@
         int importance = DEFAULT_IMPORTANCE;
         int priority = DEFAULT_PRIORITY;
         int visibility = DEFAULT_VISIBILITY;
-        Map<String, Topic> topics = new ArrayMap<>();
    }
-
-    private static class Topic {
-        Notification.Topic topic;
-        int priority = DEFAULT_PRIORITY;
-        int visibility = DEFAULT_VISIBILITY;
-        int importance = DEFAULT_IMPORTANCE;
-
-        public Topic(Notification.Topic topic) {
-            this.topic = topic;
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java b/services/core/java/com/android/server/notification/VisibilityExtractor.java
similarity index 79%
rename from services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
rename to services/core/java/com/android/server/notification/VisibilityExtractor.java
index eaa3ed3..2da2b2f 100644
--- a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
+++ b/services/core/java/com/android/server/notification/VisibilityExtractor.java
@@ -21,8 +21,8 @@
 /**
  * Determines if the given notification can display sensitive content on the lockscreen.
  */
-public class TopicVisibilityExtractor implements NotificationSignalExtractor {
-    private static final String TAG = "TopicVisibilityExtractor";
+public class VisibilityExtractor implements NotificationSignalExtractor {
+    private static final String TAG = "VisibilityExtractor";
     private static final boolean DBG = false;
 
     private RankingConfig mConfig;
@@ -42,10 +42,8 @@
             return null;
         }
 
-        final int packageVisibility = mConfig.getVisibilityOverride(
-                record.sbn.getPackageName(), record.sbn.getUid(),
-                record.sbn.getNotification().getTopic());
-        record.setPackageVisibilityOverride(packageVisibility);
+        record.setPackageVisibilityOverride(
+                mConfig.getVisibilityOverride(record.sbn.getPackageName(), record.sbn.getUid()));
 
         return null;
     }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index e7465c0..d5ed04a 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -41,6 +41,7 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.IUserManager;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
@@ -188,6 +189,8 @@
     private final File mUsersDir;
     private final File mUserListFile;
 
+    private static final IBinder mUserRestriconToken = new Binder();
+
     /**
      * User-related information that is used for persisting to flash. Only UserInfo is
      * directly exposed to other system apps.
@@ -1016,7 +1019,7 @@
         if (mAppOpsService != null) { // We skip it until system-ready.
             final long token = Binder.clearCallingIdentity();
             try {
-                mAppOpsService.setUserRestrictions(effective, userId);
+                mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId);
             } catch (RemoteException e) {
                 Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
             } finally {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e88b72f..716b96f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -33,6 +33,7 @@
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerInternal;
@@ -2035,7 +2036,7 @@
                 permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
         }
         if (permission != null) {
-            if (permission == android.Manifest.permission.SYSTEM_ALERT_WINDOW) {
+            if (android.Manifest.permission.SYSTEM_ALERT_WINDOW.equals(permission)) {
                 final int callingUid = Binder.getCallingUid();
                 // system processes will be automatically allowed privilege to draw
                 if (callingUid == Process.SYSTEM_UID) {
@@ -6075,9 +6076,20 @@
     public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
             Rect outInsets) {
         outInsets.setEmpty();
+
+        // Navigation bar and status bar.
+        getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, outInsets);
         if (mStatusBar != null) {
             outInsets.top = mStatusBarHeight;
         }
+    }
+
+    @Override
+    public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
+            Rect outInsets) {
+        outInsets.setEmpty();
+
+        // Only navigation bar
         if (mNavigationBar != null) {
             if (isNavigationBarOnBottom(displayWidth, displayHeight)) {
                 outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a1f24f7..dbaa598 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -49,6 +49,7 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.provider.Settings.Secure;
 import android.service.dreams.DreamManagerInternal;
 import android.util.EventLog;
 import android.util.Slog;
@@ -468,6 +469,9 @@
     private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners
             = new ArrayList<PowerManagerInternal.LowPowerModeListener>();
 
+    // True if brightness should be affected by twilight.
+    private boolean mBrightnessUseTwilight;
+
     private native void nativeInit();
 
     private static native void nativeAcquireSuspendBlocker(String name);
@@ -620,6 +624,9 @@
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.DOUBLE_TAP_TO_WAKE),
                     false, mSettingsObserver, UserHandle.USER_ALL);
+            resolver.registerContentObserver(Settings.Secure.getUriFor(
+                    Secure.BRIGHTNESS_USE_TWILIGHT),
+                    false, mSettingsObserver, UserHandle.USER_ALL);
             // Go.
             readConfigurationLocked();
             updateSettingsLocked();
@@ -726,6 +733,9 @@
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
                 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
 
+        mBrightnessUseTwilight = Settings.Secure.getIntForUser(resolver,
+                Secure.BRIGHTNESS_USE_TWILIGHT, 0, UserHandle.USER_CURRENT) != 0;
+
         final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE, 0) != 0;
         final boolean autoLowPowerModeConfigured = Settings.Global.getInt(resolver,
@@ -1997,6 +2007,7 @@
             mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
             mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
             mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;
+            mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;
 
             if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
                 mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
diff --git a/services/core/java/com/android/server/twilight/TwilightManager.java b/services/core/java/com/android/server/twilight/TwilightManager.java
index b3de58b..56137a4 100644
--- a/services/core/java/com/android/server/twilight/TwilightManager.java
+++ b/services/core/java/com/android/server/twilight/TwilightManager.java
@@ -20,5 +20,6 @@
 
 public interface TwilightManager {
     void registerListener(TwilightListener listener, Handler handler);
+    void unregisterListener(TwilightListener listener);
     TwilightState getCurrentState();
 }
diff --git a/services/core/java/com/android/server/twilight/TwilightService.java b/services/core/java/com/android/server/twilight/TwilightService.java
index a71961c..ac1ab64 100644
--- a/services/core/java/com/android/server/twilight/TwilightService.java
+++ b/services/core/java/com/android/server/twilight/TwilightService.java
@@ -19,12 +19,15 @@
 import com.android.server.SystemService;
 import com.android.server.TwilightCalculator;
 
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
 import android.location.Criteria;
 import android.location.Location;
 import android.location.LocationListener;
@@ -33,6 +36,9 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
 import android.text.format.DateUtils;
 import android.text.format.Time;
 import android.util.Slog;
@@ -54,6 +60,26 @@
     static final String ACTION_UPDATE_TWILIGHT_STATE =
             "com.android.server.action.UPDATE_TWILIGHT_STATE";
 
+    // The amount of time after or before sunrise over which to start adjusting
+    // twilight affected things.  We want the change to happen gradually so that
+    // it is below the threshold of perceptibility and so that the adjustment has
+    // maximum effect well after dusk.
+    private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
+
+    // Broadcast when twilight changes.
+    public static final String ACTION_TWILIGHT_CHANGED = "android.intent.action.TWILIGHT_CHANGED";
+
+    public static final String EXTRA_IS_NIGHT = "isNight";
+    public static final String EXTRA_AMOUNT = "amount";
+
+    // Amount of time the TwilightService will stay locked in an override state before switching
+    // back to auto.
+    private static final long RESET_TIME = DateUtils.HOUR_IN_MILLIS * 2;
+    private static final String EXTRA_RESET_USER = "user";
+
+    private static final String ACTION_RESET_TWILIGHT_AUTO =
+            "com.android.server.action.RESET_TWILIGHT_AUTO";
+
     final Object mLock = new Object();
 
     AlarmManager mAlarmManager;
@@ -65,6 +91,10 @@
 
     TwilightState mTwilightState;
 
+    private int mCurrentUser;
+    private boolean mLocked;
+    private boolean mBootCompleted;
+
     public TwilightService(Context context) {
         super(context);
     }
@@ -75,14 +105,93 @@
         mLocationManager = (LocationManager) getContext().getSystemService(
                 Context.LOCATION_SERVICE);
         mLocationHandler = new LocationHandler();
+        mCurrentUser = ActivityManager.getCurrentUser();
 
         IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         filter.addAction(Intent.ACTION_TIME_CHANGED);
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+        filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(ACTION_UPDATE_TWILIGHT_STATE);
-        getContext().registerReceiver(mUpdateLocationReceiver, filter);
+        getContext().registerReceiver(mReceiver, filter);
 
         publishLocalService(TwilightManager.class, mService);
+        getContext().getContentResolver().registerContentObserver(
+                Secure.getUriFor(Secure.TWILIGHT_MODE), false, mContentObserver, mCurrentUser);
+        mContentObserver.onChange(true);
+    }
+
+    @Override
+    public void onBootPhase(int phase) {
+        if (phase == PHASE_BOOT_COMPLETED) {
+            mBootCompleted = true;
+            sendBroadcast();
+        }
+    }
+
+    private void reregisterSettingObserver() {
+        final ContentResolver contentResolver = getContext().getContentResolver();
+        contentResolver.unregisterContentObserver(mContentObserver);
+        contentResolver.registerContentObserver(Secure.getUriFor(Secure.TWILIGHT_MODE), false,
+                mContentObserver, mCurrentUser);
+        mContentObserver.onChange(true);
+    }
+
+    private void setLockedState(TwilightState state) {
+        synchronized (mLock) {
+            // Make sure we aren't locked so we can set the state.
+            mLocked = false;
+            setTwilightState(state);
+            // Make sure we leave the state locked, so it cant be changed.
+            mLocked = true;
+            // TODO: Don't bother updating state when locked.
+        }
+    }
+
+    private void setTwilightState(TwilightState state) {
+        synchronized (mLock) {
+            if (mLocked) {
+                // State has been locked by secure setting, shouldn't be changed.
+                return;
+            }
+            if (!Objects.equal(mTwilightState, state)) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Twilight state changed: " + state);
+                }
+
+                mTwilightState = state;
+
+                final int listenerLen = mListeners.size();
+                for (int i = 0; i < listenerLen; i++) {
+                    mListeners.get(i).postUpdate();
+                }
+            }
+        }
+        sendBroadcast();
+    }
+
+    private void sendBroadcast() {
+        synchronized (mLock) {
+            if (mTwilightState == null) {
+                return;
+            }
+            if (mBootCompleted) {
+                Intent intent = new Intent(ACTION_TWILIGHT_CHANGED);
+                intent.putExtra(EXTRA_IS_NIGHT, mTwilightState.isNight());
+                intent.putExtra(EXTRA_AMOUNT, mTwilightState.getAmount());
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+            }
+        }
+    }
+
+    private void scheduleReset() {
+        long resetTime = System.currentTimeMillis() + RESET_TIME;
+        Intent resetIntent = new Intent(ACTION_RESET_TWILIGHT_AUTO);
+        resetIntent.putExtra(EXTRA_RESET_USER, mCurrentUser);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                getContext(), 0, resetIntent, 0);
+        mAlarmManager.cancel(pendingIntent);
+        mAlarmManager.setExact(AlarmManager.RTC, resetTime, pendingIntent);
     }
 
     private static class TwilightListenerRecord implements Runnable {
@@ -133,24 +242,22 @@
                 }
             }
         }
-    };
 
-    private void setTwilightState(TwilightState state) {
-        synchronized (mLock) {
-            if (!Objects.equal(mTwilightState, state)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Twilight state changed: " + state);
+        @Override
+        public void unregisterListener(TwilightListener listener) {
+            synchronized (mLock) {
+                for (int i = 0; i < mListeners.size(); i++) {
+                    if (mListeners.get(i).mListener == listener) {
+                        mListeners.remove(i);
+                    }
                 }
 
-                mTwilightState = state;
-
-                final int listenerLen = mListeners.size();
-                for (int i = 0; i < listenerLen; i++) {
-                    mListeners.get(i).postUpdate();
+                if (mListeners.size() == 0) {
+                    mLocationHandler.disableLocationUpdates();
                 }
             }
         }
-    }
+    };
 
     // The user has moved if the accuracy circles of the two locations don't overlap.
     private static boolean hasMoved(Location from, Location to) {
@@ -183,6 +290,7 @@
         private static final int MSG_GET_NEW_LOCATION_UPDATE = 2;
         private static final int MSG_PROCESS_NEW_LOCATION = 3;
         private static final int MSG_DO_TWILIGHT_UPDATE = 4;
+        private static final int MSG_DISABLE_LOCATION_UPDATES = 5;
 
         private static final long LOCATION_UPDATE_MS = 24 * DateUtils.HOUR_IN_MILLIS;
         private static final long MIN_LOCATION_UPDATE_MS = 30 * DateUtils.MINUTE_IN_MILLIS;
@@ -210,6 +318,10 @@
             sendEmptyMessage(MSG_ENABLE_LOCATION_UPDATES);
         }
 
+        public void disableLocationUpdates() {
+            sendEmptyMessage(MSG_DISABLE_LOCATION_UPDATES);
+        }
+
         public void requestLocationUpdate() {
             sendEmptyMessage(MSG_GET_NEW_LOCATION_UPDATE);
         }
@@ -311,6 +423,11 @@
                     }
                     break;
 
+                case MSG_DISABLE_LOCATION_UPDATES:
+                    mLocationManager.removeUpdates(mLocationListener);
+                    removeMessages(MSG_ENABLE_LOCATION_UPDATES);
+                    break;
+
                 case MSG_DO_TWILIGHT_UPDATE:
                     updateTwilightState();
                     break;
@@ -368,11 +485,6 @@
 
             final long now = System.currentTimeMillis();
 
-            // calculate yesterday's twilight
-            mTwilightCalculator.calculateTwilight(now - DateUtils.DAY_IN_MILLIS,
-                    mLocation.getLatitude(), mLocation.getLongitude());
-            final long yesterdaySunset = mTwilightCalculator.mSunset;
-
             // calculate today's twilight
             mTwilightCalculator.calculateTwilight(now,
                     mLocation.getLatitude(), mLocation.getLongitude());
@@ -385,9 +497,19 @@
                     mLocation.getLatitude(), mLocation.getLongitude());
             final long tomorrowSunrise = mTwilightCalculator.mSunrise;
 
+            float amount = 0;
+            if (isNight) {
+                if (todaySunrise == -1 || todaySunset == -1) {
+                    amount = 1;
+                } else if (now > todaySunset) {
+                    amount = Math.min(1, (now - todaySunset) / (float) TWILIGHT_ADJUSTMENT_TIME);
+                } else {
+                    amount = Math.max(0, 1
+                            - (todaySunrise - now) / (float) TWILIGHT_ADJUSTMENT_TIME);
+                }
+            }
             // set twilight state
-            TwilightState state = new TwilightState(isNight, yesterdaySunset,
-                    todaySunrise, todaySunset, tomorrowSunrise);
+            TwilightState state = new TwilightState(isNight, amount);
             if (DEBUG) {
                 Slog.d(TAG, "Updating twilight state: " + state);
             }
@@ -402,12 +524,18 @@
                 // add some extra time to be on the safe side.
                 nextUpdate += DateUtils.MINUTE_IN_MILLIS;
 
-                if (now > todaySunset) {
-                    nextUpdate += tomorrowSunrise;
-                } else if (now > todaySunrise) {
-                    nextUpdate += todaySunset;
+                if (amount == 1 || amount == 0) {
+                    if (now > todaySunset) {
+                        nextUpdate += tomorrowSunrise;
+                    } else if (now > todaySunrise) {
+                        nextUpdate += todaySunset;
+                    } else {
+                        nextUpdate += todaySunrise;
+                    }
                 } else {
-                    nextUpdate += todaySunrise;
+                    // This is the update rate while transitioning.
+                    // Leave at 10 min for now (one from above).
+                    nextUpdate += 9 * DateUtils.MINUTE_IN_MILLIS;
                 }
             }
 
@@ -423,9 +551,37 @@
         }
     }
 
-    private final BroadcastReceiver mUpdateLocationReceiver = new BroadcastReceiver() {
+    private final ContentObserver mContentObserver = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            int value = Secure.getIntForUser(getContext().getContentResolver(),
+                    Secure.TWILIGHT_MODE, Secure.TWILIGHT_MODE_LOCKED_OFF, mCurrentUser);
+            if (value == Secure.TWILIGHT_MODE_LOCKED_OFF) {
+                setLockedState(new TwilightState(false, 0));
+            } else if (value == Secure.TWILIGHT_MODE_LOCKED_ON) {
+                setLockedState(new TwilightState(true, 1));
+            } else if (value == Secure.TWILIGHT_MODE_AUTO_OVERRIDE_OFF) {
+                setLockedState(new TwilightState(false, 0));
+                scheduleReset();
+            } else if (value == Secure.TWILIGHT_MODE_AUTO_OVERRIDE_ON) {
+                setLockedState(new TwilightState(true, 1));
+                scheduleReset();
+            } else {
+                mLocked = false;
+                mLocationHandler.requestTwilightUpdate();
+            }
+        }
+    };
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+                mCurrentUser = ActivityManager.getCurrentUser();
+                reregisterSettingObserver();
+                return;
+            }
             if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())
                     && !intent.getBooleanExtra("state", false)) {
                 // Airplane mode is now off!
@@ -433,6 +589,12 @@
                 return;
             }
 
+            if (ACTION_RESET_TWILIGHT_AUTO.equals(intent.getAction())) {
+                int user = intent.getIntExtra(EXTRA_RESET_USER, 0);
+                Settings.Secure.putIntForUser(getContext().getContentResolver(),
+                        Secure.TWILIGHT_MODE, Secure.TWILIGHT_MODE_AUTO, user);
+                return;
+            }
             // Time zone has changed or alarm expired.
             mLocationHandler.requestTwilightUpdate();
         }
diff --git a/services/core/java/com/android/server/twilight/TwilightState.java b/services/core/java/com/android/server/twilight/TwilightState.java
index 91e24d7..81abc13 100644
--- a/services/core/java/com/android/server/twilight/TwilightState.java
+++ b/services/core/java/com/android/server/twilight/TwilightState.java
@@ -25,20 +25,11 @@
  */
 public class TwilightState {
     private final boolean mIsNight;
-    private final long mYesterdaySunset;
-    private final long mTodaySunrise;
-    private final long mTodaySunset;
-    private final long mTomorrowSunrise;
+    private final float mAmount;
 
-    TwilightState(boolean isNight,
-            long yesterdaySunset,
-            long todaySunrise, long todaySunset,
-            long tomorrowSunrise) {
+    TwilightState(boolean isNight, float amount) {
         mIsNight = isNight;
-        mYesterdaySunset = yesterdaySunset;
-        mTodaySunrise = todaySunrise;
-        mTodaySunset = todaySunset;
-        mTomorrowSunrise = tomorrowSunrise;
+        mAmount = amount;
     }
 
     /**
@@ -49,35 +40,11 @@
     }
 
     /**
-     * Returns the time of yesterday's sunset in the System.currentTimeMillis() timebase,
-     * or -1 if the sun never sets.
+     * For twilight affects that change gradually over time, this is the amount they
+     * should currently be in effect.
      */
-    public long getYesterdaySunset() {
-        return mYesterdaySunset;
-    }
-
-    /**
-     * Returns the time of today's sunrise in the System.currentTimeMillis() timebase,
-     * or -1 if the sun never rises.
-     */
-    public long getTodaySunrise() {
-        return mTodaySunrise;
-    }
-
-    /**
-     * Returns the time of today's sunset in the System.currentTimeMillis() timebase,
-     * or -1 if the sun never sets.
-     */
-    public long getTodaySunset() {
-        return mTodaySunset;
-    }
-
-    /**
-     * Returns the time of tomorrow's sunrise in the System.currentTimeMillis() timebase,
-     * or -1 if the sun never rises.
-     */
-    public long getTomorrowSunrise() {
-        return mTomorrowSunrise;
+    public float getAmount() {
+        return mAmount;
     }
 
     @Override
@@ -88,10 +55,7 @@
     public boolean equals(TwilightState other) {
         return other != null
                 && mIsNight == other.mIsNight
-                && mYesterdaySunset == other.mYesterdaySunset
-                && mTodaySunrise == other.mTodaySunrise
-                && mTodaySunset == other.mTodaySunset
-                && mTomorrowSunrise == other.mTomorrowSunrise;
+                && mAmount == other.mAmount;
     }
 
     @Override
@@ -103,10 +67,7 @@
     public String toString() {
         DateFormat f = DateFormat.getDateTimeInstance();
         return "{TwilightState: isNight=" + mIsNight
-                + ", mYesterdaySunset=" + f.format(new Date(mYesterdaySunset))
-                + ", mTodaySunrise=" + f.format(new Date(mTodaySunrise))
-                + ", mTodaySunset=" + f.format(new Date(mTodaySunset))
-                + ", mTomorrowSunrise=" + f.format(new Date(mTomorrowSunrise))
+                + ", mAmount=" + mAmount
                 + "}";
     }
 }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index a16c8d1..7378bde 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1072,6 +1072,7 @@
         }
     }
 
+    @Override
     public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb, final int which,
             Bundle outParams, int wallpaperUserId) {
         if (wallpaperUserId != UserHandle.getCallingUserId()) {
@@ -1086,19 +1087,17 @@
         }
 
         synchronized (mLock) {
-            WallpaperData wallpaper = null;
-            if (which == FLAG_SET_LOCK) {
-                wallpaper = mLockWallpaperMap.get(wallpaperUserId);
+            final SparseArray<WallpaperData> whichSet =
+                    (which == FLAG_SET_LOCK) ? mLockWallpaperMap : mWallpaperMap;
+            WallpaperData wallpaper = whichSet.get(wallpaperUserId);
+            if (wallpaper == null) {
+                // common case, this is the first lookup post-boot of the system or
+                // unified lock, so we bring up the saved state lazily now and recheck.
+                loadSettingsLocked(wallpaperUserId);
+                wallpaper = whichSet.get(wallpaperUserId);
                 if (wallpaper == null) {
-                    // If you ask for the lock wallpaper specifically and there isn't one,
-                    // we say so rather than returning the system wallpaper as fallback.
                     return null;
                 }
-            } else {
-                wallpaper = mWallpaperMap.get(wallpaperUserId);
-            }
-            if (wallpaper == null) {
-                return null;
             }
             try {
                 if (outParams != null) {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 1821487..5cb7099 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -46,13 +46,13 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.AppTransitionAnimationSpec;
@@ -63,8 +63,6 @@
 import android.view.animation.AnimationSet;
 import android.view.animation.AnimationUtils;
 import android.view.animation.ClipRectAnimation;
-import android.view.animation.ClipRectLRAnimation;
-import android.view.animation.ClipRectTBAnimation;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 import android.view.animation.ScaleAnimation;
@@ -73,10 +71,11 @@
 import com.android.internal.util.DumpUtils.Dump;
 import com.android.server.AttributeCache;
 import com.android.server.wm.WindowManagerService.H;
+import com.android.server.wm.animation.ClipRectLRAnimation;
+import com.android.server.wm.animation.ClipRectTBAnimation;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -135,6 +134,16 @@
     private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.5f;
 
     static final int DEFAULT_APP_TRANSITION_DURATION = 336;
+
+    /** Interpolator to be used for animations that respond directly to a touch */
+    static final Interpolator TOUCH_RESPONSE_INTERPOLATOR =
+            new PathInterpolator(0.3f, 0f, 0.1f, 1f);
+
+    /**
+     * Maximum duration for the clip reveal animation. This is used when there is a lot of movement
+     * involved, to make it more understandable.
+     */
+    private static final int MAX_CLIP_REVEAL_TRANSITION_DURATION = 420;
     private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336;
     private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 336;
     private static final long APP_TRANSITION_TIMEOUT_MS = 5000;
@@ -199,17 +208,17 @@
     private final Interpolator mFastOutLinearInInterpolator;
     private final Interpolator mClipHorizontalInterpolator = new PathInterpolator(0, 0, 0.4f, 1f);
 
-    /** Interpolator to be used for animations that respond directly to a touch */
-    private final Interpolator mTouchResponseInterpolator =
-            new PathInterpolator(0.3f, 0f, 0.1f, 1f);
-
     private final int mClipRevealTranslationY;
 
     private int mCurrentUserId = 0;
+    private long mLastClipRevealTransitionDuration = DEFAULT_APP_TRANSITION_DURATION;
 
     private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>();
     private final ExecutorService mDefaultExecutor = Executors.newSingleThreadExecutor();
 
+    private int mLastClipRevealMaxTranslation;
+    private boolean mLastHadClipReveal;
+
     AppTransition(Context context, WindowManagerService service) {
         mContext = context;
         mService = service;
@@ -331,19 +340,25 @@
         if (!isRunning()) {
             mAppTransitionState = APP_STATE_IDLE;
             notifyAppTransitionPendingLocked();
+            mLastHadClipReveal = false;
+            mLastClipRevealMaxTranslation = 0;
+            mLastClipRevealTransitionDuration = DEFAULT_APP_TRANSITION_DURATION;
             return true;
         }
         return false;
     }
 
-    void goodToGo(AppWindowAnimator openingAppAnimator, AppWindowAnimator closingAppAnimator) {
+    void goodToGo(AppWindowAnimator topOpeningAppAnimator, AppWindowAnimator topClosingAppAnimator,
+            ArraySet<AppWindowToken> openingApps, ArraySet<AppWindowToken> closingApps) {
         mNextAppTransition = TRANSIT_UNSET;
         mAppTransitionState = APP_STATE_RUNNING;
         notifyAppTransitionStartingLocked(
-                openingAppAnimator != null ? openingAppAnimator.mAppToken.token : null,
-                closingAppAnimator != null ? closingAppAnimator.mAppToken.token : null,
-                openingAppAnimator != null ? openingAppAnimator.animation : null,
-                closingAppAnimator != null ? closingAppAnimator.animation : null);
+                topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null,
+                topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null,
+                topOpeningAppAnimator != null ? topOpeningAppAnimator.animation : null,
+                topClosingAppAnimator != null ? topClosingAppAnimator.animation : null);
+        mService.getDefaultDisplayContentLocked().getDockedDividerController()
+                .notifyAppTransitionStarting(openingApps, closingApps);
     }
 
     void clear() {
@@ -632,50 +647,118 @@
                 bitmap, new Rect(left, top, left + width, top + height));
     }
 
-    private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame) {
+    /**
+     * @return the duration of the last clip reveal animation
+     */
+    long getLastClipRevealTransitionDuration() {
+        return mLastClipRevealTransitionDuration;
+    }
+
+    /**
+     * @return the maximum distance the app surface is traveling of the last clip reveal animation
+     */
+    int getLastClipRevealMaxTranslation() {
+        return mLastClipRevealMaxTranslation;
+    }
+
+    /**
+     * @return true if in the last app transition had a clip reveal animation, false otherwise
+     */
+    boolean hadClipRevealAnimation() {
+        return mLastHadClipReveal;
+    }
+
+    /**
+     * Calculates the duration for the clip reveal animation. If the clip is "cut off", meaning that
+     * the start rect is outside of the target rect, and there is a lot of movement going on.
+     *
+     * @param cutOff whether the start rect was not fully contained by the end rect
+     * @param translationX the total translation the surface moves in x direction
+     * @param translationY the total translation the surfaces moves in y direction
+     * @param displayFrame our display frame
+     *
+     * @return the duration of the clip reveal animation, in milliseconds
+     */
+    private long calculateClipRevealTransitionDuration(boolean cutOff, float translationX,
+            float translationY, Rect displayFrame) {
+        if (!cutOff) {
+            return DEFAULT_APP_TRANSITION_DURATION;
+        }
+        final float fraction = Math.max(Math.abs(translationX) / displayFrame.width(),
+                Math.abs(translationY) / displayFrame.height());
+        return (long) (DEFAULT_APP_TRANSITION_DURATION + fraction *
+                (MAX_CLIP_REVEAL_TRANSITION_DURATION - DEFAULT_APP_TRANSITION_DURATION));
+    }
+
+    private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame,
+            Rect displayFrame) {
         final Animation anim;
         if (enter) {
-            // Reveal will expand and move faster in horizontal direction
-
             final int appWidth = appFrame.width();
             final int appHeight = appFrame.height();
+
             // mTmpRect will contain an area around the launcher icon that was pressed. We will
             // clip reveal from that area in the final area of the app.
             getDefaultNextAppTransitionStartRect(mTmpRect);
 
             float t = 0f;
             if (appHeight > 0) {
-                t = (float) mTmpRect.left / appHeight;
+                t = (float) mTmpRect.top / displayFrame.height();
             }
-            int translationY = mClipRevealTranslationY + (int)(appHeight / 7f * t);
-
+            int translationY = mClipRevealTranslationY + (int)(displayFrame.height() / 7f * t);
+            int translationX = 0;
+            int translationYCorrection = translationY;
             int centerX = mTmpRect.centerX();
             int centerY = mTmpRect.centerY();
             int halfWidth = mTmpRect.width() / 2;
             int halfHeight = mTmpRect.height() / 2;
+            int clipStartX = centerX - halfWidth - appFrame.left;
+            int clipStartY = centerY - halfHeight - appFrame.top;
+            boolean cutOff = false;
+
+            // If the starting rectangle is fully or partially outside of the target rectangle, we
+            // need to start the clipping at the edge and then achieve the rest with translation
+            // and extending the clip rect from that edge.
+            if (appFrame.top > centerY - halfHeight) {
+                translationY = (centerY - halfHeight) - appFrame.top;
+                translationYCorrection = 0;
+                clipStartY = 0;
+                cutOff = true;
+            }
+            if (appFrame.left > centerX - halfWidth) {
+                translationX = (centerX - halfWidth) - appFrame.left;
+                clipStartX = 0;
+                cutOff = true;
+            }
+            if (appFrame.right < centerX + halfWidth) {
+                translationX = (centerX + halfWidth) - appFrame.right;
+                clipStartX = appWidth - mTmpRect.width();
+                cutOff = true;
+            }
+            final long duration = calculateClipRevealTransitionDuration(cutOff, translationX,
+                    translationY, displayFrame);
 
             // Clip third of the from size of launch icon, expand to full width/height
             Animation clipAnimLR = new ClipRectLRAnimation(
-                    centerX - halfWidth, centerX + halfWidth, 0, appWidth);
+                    clipStartX, clipStartX + mTmpRect.width(), 0, appWidth);
             clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
-            clipAnimLR.setDuration((long) (DEFAULT_APP_TRANSITION_DURATION / 2.5f));
+            clipAnimLR.setDuration((long) (duration / 2.5f));
 
-            Animation clipAnimTB = new ClipRectTBAnimation(centerY - halfHeight - translationY,
-                    centerY + halfHeight/ 2 - translationY, 0, appHeight);
-            clipAnimTB.setInterpolator(mTouchResponseInterpolator);
-            clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+            TranslateAnimation translate = new TranslateAnimation(translationX, 0, translationY, 0);
+            translate.setInterpolator(cutOff ? TOUCH_RESPONSE_INTERPOLATOR
+                    : mLinearOutSlowInInterpolator);
+            translate.setDuration(duration);
 
-            // We might be animating entrance of a docked task, so we need the translate to account
-            // for the app frame in which the window will reside. Every other calculation here
-            // is performed as if the window started at 0,0.
-            translationY -= appFrame.top;
-            TranslateAnimation translate = new TranslateAnimation(-appFrame.left, 0, translationY,
-                    0);
-            translate.setInterpolator(mLinearOutSlowInInterpolator);
-            translate.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+            Animation clipAnimTB = new ClipRectTBAnimation(
+                    clipStartY, clipStartY + mTmpRect.height(),
+                    0, appHeight,
+                    translationYCorrection, 0,
+                    mLinearOutSlowInInterpolator);
+            clipAnimTB.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
+            clipAnimTB.setDuration(duration);
 
             // Quick fade-in from icon to app window
-            final int alphaDuration = DEFAULT_APP_TRANSITION_DURATION / 4;
+            final long alphaDuration = duration / 4;
             AlphaAnimation alpha = new AlphaAnimation(0.5f, 1);
             alpha.setDuration(alphaDuration);
             alpha.setInterpolator(mLinearOutSlowInInterpolator);
@@ -688,6 +771,13 @@
             set.setZAdjustment(Animation.ZORDER_TOP);
             set.initialize(appWidth, appHeight, appWidth, appHeight);
             anim = set;
+            mLastHadClipReveal = true;
+            mLastClipRevealTransitionDuration = duration;
+
+            // If the start rect was full inside the target rect (cutOff == false), we don't need
+            // to store the translation, because it's only used if cutOff == true.
+            mLastClipRevealMaxTranslation = cutOff
+                    ? Math.max(Math.abs(translationY), Math.abs(translationX)) : 0;
         } else {
             final long duration;
             switch (transit) {
@@ -794,7 +884,7 @@
             // Animation up from the thumbnail to the full screen
             Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
                     mTmpRect.left + (thumbWidth / 2f), mTmpRect.top + (thumbHeight / 2f));
-            scale.setInterpolator(mTouchResponseInterpolator);
+            scale.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
             scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
             Animation alpha = new AlphaAnimation(1f, 0f);
             alpha.setInterpolator(mThumbnailFadeOutInterpolator);
@@ -802,7 +892,7 @@
             final float toX = appRect.left + appRect.width() / 2 -
                     (mTmpRect.left + thumbWidth / 2);
             Animation translate = new TranslateAnimation(0, toX, 0, toY);
-            translate.setInterpolator(mTouchResponseInterpolator);
+            translate.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
             translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
 
             // This AnimationSet uses the Interpolators assigned above.
@@ -815,7 +905,7 @@
             // Animation down from the full screen to the thumbnail
             Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
                     mTmpRect.left + (thumbWidth / 2f), mTmpRect.top + (thumbHeight / 2f));
-            scale.setInterpolator(mTouchResponseInterpolator);
+            scale.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
             scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
             Animation alpha = new AlphaAnimation(0f, 1f);
             alpha.setInterpolator(mThumbnailFadeInInterpolator);
@@ -823,7 +913,7 @@
             final float toX = appRect.left + appRect.width() / 2 -
                     (mTmpRect.left + thumbWidth / 2);
             Animation translate = new TranslateAnimation(toX, 0, toY, 0);
-            translate.setInterpolator(mTouchResponseInterpolator);
+            translate.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
             translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
 
             // This AnimationSet uses the Interpolators assigned above.
@@ -835,7 +925,7 @@
 
         }
         return prepareThumbnailAnimationWithDuration(a, appWidth, appRect.height(), 0,
-                mTouchResponseInterpolator);
+                TOUCH_RESPONSE_INTERPOLATOR);
     }
 
     /**
@@ -967,7 +1057,7 @@
         int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
                 THUMBNAIL_APP_TRANSITION_DURATION);
         return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
-                mTouchResponseInterpolator);
+                TOUCH_RESPONSE_INTERPOLATOR);
     }
 
     private Animation createAspectScaledThumbnailEnterFreeformAnimationLocked(Rect frame,
@@ -1219,8 +1309,9 @@
      *                      bigger.
      */
     Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
-            int orientation, Rect frame, Rect insets, @Nullable Rect surfaceInsets,
-            boolean isVoiceInteraction, boolean freeform, int taskId) {
+            int orientation, Rect frame, Rect displayFrame, Rect insets,
+            @Nullable Rect surfaceInsets, boolean isVoiceInteraction, boolean freeform,
+            int taskId) {
         Animation a;
         if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
                 || transit == TRANSIT_TASK_OPEN
@@ -1265,7 +1356,7 @@
                     + " transit=" + appTransitionToString(transit)
                     + " Callers=" + Debug.getCallers(3));
         } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
-            a = createClipRevealAnimationLocked(transit, enter, frame);
+            a = createClipRevealAnimationLocked(transit, enter, frame, displayFrame);
             if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
                     "applyAnimation:"
                             + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 2a091ba..12c62bd 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -254,7 +254,7 @@
                 // In cases where there are multiple windows, we prefer the non-exiting window. This
                 // happens for example when replacing windows during an activity relaunch. When
                 // constructing the animation, we want the new window, not the exiting one.
-                if (win.mExiting) {
+                if (win.mAnimatingExit) {
                     candidate = win;
                 } else {
                     return win;
@@ -307,11 +307,11 @@
             // If the app already requested to remove its window, we don't modify
             // its exiting state. Otherwise the stale window won't get removed on
             // exit and could cause focus to be given to the wrong window.
-            if (!(win.mRemoveOnExit && win.mExiting)) {
-                win.mExiting = exiting;
+            if (!(win.mRemoveOnExit && win.mAnimatingExit)) {
+                win.mAnimatingExit = exiting;
             }
             // If we're no longer exiting, remove the window from destroying list
-            if (!win.mExiting && win.mDestroying) {
+            if (!win.mAnimatingExit && win.mDestroying) {
                 win.mDestroying = false;
                 service.mDestroySurface.remove(win);
             }
@@ -330,13 +330,13 @@
                 continue;
             }
 
-            if (!mAppStopped && !win.mClientRemoveRequested) {
+            if (!(mAppStopped || win.mWindowRemovalAllowed)) {
                 continue;
             }
 
             win.destroyOrSaveSurface();
             if (win.mRemoveOnExit) {
-                win.mExiting = false;
+                win.mAnimatingExit = false;
                 service.removeWindowInnerLocked(win);
             }
             final DisplayContent displayContent = win.getDisplayContent();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 144d7ac..73cea52 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -127,7 +127,7 @@
         isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
         mService = service;
         initializeDisplayBaseInfo();
-        mDividerControllerLocked = new DockedStackDividerController(service.mContext, this);
+        mDividerControllerLocked = new DockedStackDividerController(service, this);
         mDimLayerController = new DimLayerController(this);
     }
 
@@ -606,12 +606,24 @@
         return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mStacks;
     }
 
+    /**
+     * @return The docked stack, but only if it is visible, and {@code null} otherwise.
+     */
     TaskStack getDockedStackLocked() {
         final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
         return (stack != null && stack.isVisibleLocked()) ? stack : null;
     }
 
     /**
+     * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
+     * visible, as long as it's not hidden because the current user doesn't have any tasks there.
+     */
+    TaskStack getDockedStackVisibleForUserLocked() {
+        final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
+        return (stack != null && stack.isVisibleForUserLocked()) ? stack : null;
+    }
+
+    /**
      * Find the visible, touch-deliverable window under the given point
      */
     WindowState getTouchableWinAtPointLocked(float xf, float yf) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 75c06ff..b6aa3f2 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -20,10 +20,13 @@
 import android.graphics.Rect;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.IDockedStackListener;
 import android.view.SurfaceControl;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
 
 import com.android.server.wm.DimLayer.DimLayerUser;
 
@@ -35,6 +38,8 @@
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
+import static com.android.server.wm.AppTransition.DEFAULT_APP_TRANSITION_DURATION;
+import static com.android.server.wm.AppTransition.TOUCH_RESPONSE_INTERPOLATOR;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -45,25 +50,65 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "DockedStackDividerController" : TAG_WM;
 
+    /**
+     * The fraction during the maximize/clip reveal animation the divider meets the edge of the clip
+     * revealing surface at the earliest.
+     */
+    private static final float CLIP_REVEAL_MEET_EARLIEST = 0.6f;
+
+    /**
+     * The fraction during the maximize/clip reveal animation the divider meets the edge of the clip
+     * revealing surface at the latest.
+     */
+    private static final float CLIP_REVEAL_MEET_LAST = 1f;
+
+    /**
+     * If the app translates at least CLIP_REVEAL_MEET_FRACTION_MIN * minimize distance, we start
+     * meet somewhere between {@link #CLIP_REVEAL_MEET_LAST} and {@link #CLIP_REVEAL_MEET_EARLIEST}.
+     */
+    private static final float CLIP_REVEAL_MEET_FRACTION_MIN = 0.4f;
+
+    /**
+     * If the app translates equals or more than CLIP_REVEAL_MEET_FRACTION_MIN * minimize distance,
+     * we meet at {@link #CLIP_REVEAL_MEET_EARLIEST}.
+     */
+    private static final float CLIP_REVEAL_MEET_FRACTION_MAX = 0.8f;
+
+    private final WindowManagerService mService;
     private final DisplayContent mDisplayContent;
     private final int mDividerWindowWidth;
     private final int mDividerInsets;
     private boolean mResizing;
     private WindowState mWindow;
     private final Rect mTmpRect = new Rect();
+    private final Rect mTmpRect2 = new Rect();
     private final Rect mLastRect = new Rect();
     private boolean mLastVisibility = false;
     private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
             = new RemoteCallbackList<>();
     private final DimLayer mDimLayer;
 
-    DockedStackDividerController(Context context, DisplayContent displayContent) {
+    private boolean mMinimizedDock;
+    private boolean mAnimating;
+    private boolean mAnimationStarted;
+    private long mAnimationStartTime;
+    private float mAnimationStart;
+    private float mAnimationTarget;
+    private long mAnimationDuration;
+    private final Interpolator mMinimizedDockInterpolator;
+    private float mMaximizeMeetFraction;
+
+    DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) {
+        mService = service;
         mDisplayContent = displayContent;
+        final Context context = service.mContext;
         mDividerWindowWidth = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_thickness);
         mDividerInsets = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_insets);
         mDimLayer = new DimLayer(displayContent.mService, this, displayContent.getDisplayId());
+        mMinimizedDockInterpolator = AnimationUtils.loadInterpolator(
+                context, android.R.interpolator.fast_out_slow_in);
     }
 
     boolean isResizing() {
@@ -180,6 +225,19 @@
         mDockedStackListeners.finishBroadcast();
     }
 
+    void notifyDockedStackMinimizedChanged(boolean minimizedDock, long animDuration) {
+        final int size = mDockedStackListeners.beginBroadcast();
+        for (int i = 0; i < size; ++i) {
+            final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
+            try {
+                listener.onDockedStackMinimizedChanged(minimizedDock, animDuration);
+            } catch (RemoteException e) {
+                Slog.e(TAG_WM, "Error delivering minimized dock changed event.", e);
+            }
+        }
+        mDockedStackListeners.finishBroadcast();
+    }
+
     void registerDockedStackListener(IDockedStackListener listener) {
         mDockedStackListeners.register(listener);
         notifyDockedDividerVisibilityChanged(wasVisible());
@@ -207,6 +265,183 @@
         SurfaceControl.closeTransaction();
     }
 
+    /**
+     * Notifies the docked stack divider controller of a visibility change that happens without
+     * an animation.
+     */
+    void notifyAppVisibilityChanged(AppWindowToken wtoken, boolean visible) {
+        final Task task = wtoken.mTask;
+        if (!task.isHomeTask() || !task.isVisibleForUser()) {
+            return;
+        }
+
+        // If the stack is completely offscreen, this might just be an intermediate state when
+        // docking a task/launching recents at the same time, but home doesn't actually get
+        // visible after the state settles in.
+        if (isWithinDisplay(task)
+                && mDisplayContent.getDockedStackVisibleForUserLocked() != null) {
+            setMinimizedDockedStack(visible, false /* animate */);
+        }
+    }
+
+    void notifyAppTransitionStarting(ArraySet<AppWindowToken> openingApps,
+            ArraySet<AppWindowToken> closingApps) {
+        if (containsHomeTaskWithinDisplay(openingApps)) {
+            setMinimizedDockedStack(true /* minimized */, true /* animate */);
+        } else if (containsHomeTaskWithinDisplay(closingApps)) {
+            setMinimizedDockedStack(false /* minimized */, true /* animate */);
+        }
+    }
+
+    private boolean containsHomeTaskWithinDisplay(ArraySet<AppWindowToken> apps) {
+        for (int i = apps.size() - 1; i >= 0; i--) {
+            final Task task = apps.valueAt(i).mTask;
+            if (task != null && task.isHomeTask()) {
+                return isWithinDisplay(task);
+            }
+        }
+        return false;
+    }
+
+    private boolean isWithinDisplay(Task task) {
+        task.mStack.getBounds(mTmpRect);
+        mDisplayContent.getLogicalDisplayRect(mTmpRect2);
+        return mTmpRect.intersect(mTmpRect2);
+    }
+
+    /**
+     * Sets whether the docked stack is currently in a minimized state, i.e. all the tasks in the
+     * docked stack are heavily clipped so you can only see a minimal peek state.
+     *
+     * @param minimizedDock Whether the docked stack is currently minimized.
+     * @param animate Whether to animate the change.
+     */
+    private void setMinimizedDockedStack(boolean minimizedDock, boolean animate) {
+        if (minimizedDock == mMinimizedDock
+                || mDisplayContent.getDockedStackVisibleForUserLocked() == null) {
+            return;
+        }
+
+        mMinimizedDock = minimizedDock;
+        if (minimizedDock) {
+            if (animate) {
+                startAdjustAnimation(0f, 1f);
+            } else {
+                setMinimizedDockedStack(true);
+            }
+        } else {
+            if (animate) {
+                startAdjustAnimation(1f, 0f);
+            } else {
+                setMinimizedDockedStack(false);
+            }
+        }
+    }
+
+    private void startAdjustAnimation(float from, float to) {
+        mAnimating = true;
+        mAnimationStarted = false;
+        mAnimationStart = from;
+        mAnimationTarget = to;
+    }
+
+    private void setMinimizedDockedStack(boolean minimized) {
+        final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked();
+        if (stack == null) {
+            return;
+        }
+        if (stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f)) {
+            mService.mWindowPlacerLocked.performSurfacePlacement();
+        }
+        notifyDockedStackMinimizedChanged(minimized, 0);
+    }
+
+    private boolean isAnimationMaximizing() {
+        return mAnimationTarget == 0f;
+    }
+
+    public boolean animate(long now) {
+        if (!mAnimating) {
+            return false;
+        }
+
+        final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked();
+        if (!mAnimationStarted) {
+            mAnimationStarted = true;
+            mAnimationStartTime = now;
+            final long transitionDuration = isAnimationMaximizing()
+                    ? mService.mAppTransition.getLastClipRevealTransitionDuration()
+                    : DEFAULT_APP_TRANSITION_DURATION;
+            mAnimationDuration = (long)
+                    (transitionDuration * mService.getTransitionAnimationScaleLocked());
+            mMaximizeMeetFraction = getClipRevealMeetFraction(stack);
+            notifyDockedStackMinimizedChanged(mMinimizedDock,
+                    (long) (mAnimationDuration * mMaximizeMeetFraction));
+        }
+        float t = Math.min(1f, (float) (now - mAnimationStartTime) / mAnimationDuration);
+        t = (isAnimationMaximizing() ? TOUCH_RESPONSE_INTERPOLATOR : mMinimizedDockInterpolator)
+                .getInterpolation(t);
+        if (stack != null) {
+            if (stack.setAdjustedForMinimizedDock(getMinimizeAmount(stack, t))) {
+                mService.mWindowPlacerLocked.performSurfacePlacement();
+            }
+        }
+        if (t >= 1.0f) {
+            mAnimating = false;
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Gets the amount how much to minimize a stack depending on the interpolated fraction t.
+     */
+    private float getMinimizeAmount(TaskStack stack, float t) {
+        final float naturalAmount = t * mAnimationTarget + (1 - t) * mAnimationStart;
+        if (isAnimationMaximizing()) {
+            return adjustMaximizeAmount(stack, t, naturalAmount);
+        } else {
+            return naturalAmount;
+        }
+    }
+
+    /**
+     * When maximizing the stack during a clip reveal transition, this adjusts the minimize amount
+     * during the transition such that the edge of the clip reveal rect is met earlier in the
+     * transition so we don't create a visible "hole", but only if both the clip reveal and the
+     * docked stack divider start from about the same portion on the screen.
+     */
+    private float adjustMaximizeAmount(TaskStack stack, float t, float naturalAmount) {
+        if (mMaximizeMeetFraction == 1f) {
+            return naturalAmount;
+        }
+        final int minimizeDistance = stack.getMinimizeDistance();
+        float startPrime = mService.mAppTransition.getLastClipRevealMaxTranslation()
+                / (float) minimizeDistance;
+        final float amountPrime = t * mAnimationTarget + (1 - t) * startPrime;
+        final float t2 = Math.min(t / mMaximizeMeetFraction, 1);
+        return amountPrime * t2 + naturalAmount * (1 - t2);
+    }
+
+    /**
+     * Retrieves the animation fraction at which the docked stack has to meet the clip reveal
+     * edge. See {@link #adjustMaximizeAmount}.
+     */
+    private float getClipRevealMeetFraction(TaskStack stack) {
+        if (!isAnimationMaximizing() || stack == null ||
+                !mService.mAppTransition.hadClipRevealAnimation()) {
+            return 1f;
+        }
+        final int minimizeDistance = stack.getMinimizeDistance();
+        final float fraction = Math.abs(mService.mAppTransition.getLastClipRevealMaxTranslation())
+                / (float) minimizeDistance;
+        final float t = Math.max(0, Math.min(1, (fraction - CLIP_REVEAL_MEET_FRACTION_MIN)
+                / (CLIP_REVEAL_MEET_FRACTION_MAX - CLIP_REVEAL_MEET_FRACTION_MIN)));
+        return CLIP_REVEAL_MEET_EARLIEST
+                + (1 - t) * (CLIP_REVEAL_MEET_LAST - CLIP_REVEAL_MEET_EARLIEST);
+    }
+
     @Override
     public boolean isFullscreen() {
         return false;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index fe55e80..325005b 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -357,6 +357,10 @@
         return !mHomeTask && (isResizeable() || mResizeMode == RESIZE_MODE_CROP_WINDOWS);
     }
 
+    boolean isHomeTask() {
+        return mHomeTask;
+    }
+
     private boolean inCropWindowsResizeMode() {
         return !mHomeTask && !isResizeable() && mResizeMode == RESIZE_MODE_CROP_WINDOWS;
     }
@@ -639,6 +643,19 @@
         return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
     }
 
+    boolean isVisibleForUser() {
+        for (int i = mAppTokens.size() - 1; i >= 0; i--) {
+            final AppWindowToken appToken = mAppTokens.get(i);
+            for (int j = appToken.allAppWindows.size() - 1; j >= 0; j--) {
+                WindowState window = appToken.allAppWindows.get(j);
+                if (!window.isHiddenFromUserLocked()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     boolean inHomeStack() {
         return mStack != null && mStack.mStackId == HOME_STACK_ID;
     }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 8409058..06e5ac5 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -75,9 +75,6 @@
     /** Content limits relative to the DisplayContent this sits in. */
     private Rect mBounds = new Rect();
 
-    /** Screen content area excluding IM windows, etc. */
-    private final Rect mContentBounds = new Rect();
-
     /** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
     private final Rect mAdjustedBounds = new Rect();
 
@@ -98,14 +95,27 @@
 
     /** Detach this stack from its display when animation completes. */
     boolean mDeferDetach;
-    private boolean mUpdateBoundsAfterRotation = false;
+
+    // Display rotation as of the last time the display information was updated for this stack.
+    private int mLastUpdateDisplayInfoRotation = -1;
+    // Display rotation as of the last time the configuration was updated for this stack.
+    private int mLastConfigChangedRotation = -1;
 
     // Whether the stack and all its tasks is currently being drag-resized
     private boolean mDragResizing;
 
+    private final Rect mLastContentBounds = new Rect();
+    private final Rect mTmpAdjustedBounds = new Rect();
+    private boolean mAdjustedForIme;
+    private WindowState mImeWin;
+    private float mMinimizeAmount;
+    private final int mDockedStackMinimizeThickness;
+
     TaskStack(WindowManagerService service, int stackId) {
         mService = service;
         mStackId = stackId;
+        mDockedStackMinimizeThickness = service.mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_minimize_thickness);
         EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
     }
 
@@ -174,7 +184,27 @@
         return mTmpRect.equals(bounds);
     }
 
-    void alignTasksToAdjustedBounds(final Rect adjustedBounds) {
+    /**
+     * Overrides the adjusted bounds, i.e. sets temporary layout bounds which are different from
+     * the normal task bounds.
+     *
+     * @param bounds The adjusted bounds.
+     * @param keepInsets Whether to keep the insets from the original bounds or to calculate new
+     *                   ones depending on the adjusted bounds.
+     */
+    private void setAdjustedBounds(Rect bounds, boolean keepInsets) {
+        if (mAdjustedBounds.equals(bounds)) {
+            return;
+        }
+
+        mAdjustedBounds.set(bounds);
+        final boolean adjusted = !mAdjustedBounds.isEmpty();
+        alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : mBounds,
+                adjusted && keepInsets ? mBounds : null);
+        mDisplayContent.layoutNeeded = true;
+    }
+
+    private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
         if (mFullscreen) {
             return;
         }
@@ -187,72 +217,15 @@
                 task.resizeLocked(null, null, false /* forced */);
                 task.getBounds(mTmpRect2);
                 task.scrollLocked(mTmpRect2);
-            } else if (task.isResizeable()) {
+            } else if (task.isResizeable() && task.mOverrideConfig != Configuration.EMPTY) {
                 task.getBounds(mTmpRect2);
                 mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top);
+                task.setTempInsetBounds(tempInsetBounds);
                 task.resizeLocked(mTmpRect2, task.mOverrideConfig, false /* forced */);
             }
         }
     }
 
-    void adjustForIME(final WindowState imeWin) {
-        final int dockedSide = getDockSide();
-        final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
-        final Rect adjustedBounds = mAdjustedBounds;
-        if (imeWin == null || !dockedTopOrBottom) {
-            // If mContentBounds is already empty, it means we're not applying
-            // any adjustments, so nothing to do; otherwise clear any adjustments.
-            if (!mContentBounds.isEmpty()) {
-                mContentBounds.setEmpty();
-                adjustedBounds.set(mBounds);
-                alignTasksToAdjustedBounds(adjustedBounds);
-            }
-            return;
-        }
-
-        final Rect displayContentRect = mTmpRect;
-        final Rect contentBounds = mTmpRect2;
-
-        // Calculate the content bounds excluding the area occupied by IME
-        mDisplayContent.getContentRect(displayContentRect);
-        contentBounds.set(displayContentRect);
-        int imeTop = Math.max(imeWin.getDisplayFrameLw().top, contentBounds.top);
-        imeTop += imeWin.getGivenContentInsetsLw().top;
-        if (contentBounds.bottom > imeTop) {
-            contentBounds.bottom = imeTop;
-        }
-
-        // If content bounds not changing, nothing to do.
-        if (mContentBounds.equals(contentBounds)) {
-            return;
-        }
-
-        // Content bounds changed, need to apply adjustments depending on dock sides.
-        mContentBounds.set(contentBounds);
-        adjustedBounds.set(mBounds);
-        final int yOffset = displayContentRect.bottom - contentBounds.bottom;
-
-        if (dockedSide == DOCKED_TOP) {
-            // If this stack is docked on top, we make it smaller so the bottom stack is not
-            // occluded by IME. We shift its bottom up by the height of the IME (capped by
-            // the display content rect). Note that we don't change the task bounds.
-            adjustedBounds.bottom = Math.max(
-                    adjustedBounds.bottom - yOffset, displayContentRect.top);
-        } else {
-            // If this stack is docked on bottom, we shift it up so that it's not occluded by
-            // IME. We try to move it up by the height of the IME window (although the best
-            // we could do is to make the top stack fully collapsed).
-            final int dividerWidth = mDisplayContent.mDividerControllerLocked.getContentWidth();
-            adjustedBounds.top = Math.max(
-                    adjustedBounds.top - yOffset, displayContentRect.top + dividerWidth);
-            adjustedBounds.bottom = adjustedBounds.top + mBounds.height();
-
-            // We also move the member tasks together, taking care not to resize them.
-            // Resizing might cause relaunch, and IME window may not come back after that.
-            alignTasksToAdjustedBounds(adjustedBounds);
-        }
-    }
-
     private boolean setBounds(Rect bounds) {
         boolean oldFullscreen = mFullscreen;
         int rotation = Surface.ROTATION_0;
@@ -281,14 +254,7 @@
         mBounds.set(bounds);
         mRotation = rotation;
 
-        // Clear the adjusted content bounds as they're no longer valid.
-        // If IME is still visible, these will be re-applied.
-        // Note that we don't clear mContentBounds here, so that we know the last IME
-        // adjust we applied.
-        // If user starts dragging the dock divider while IME is visible, the new bounds
-        // we received are based on the actual screen location of the divider. It already
-        // accounted for the IME window, so we don't want to adjust again.
-        mAdjustedBounds.set(mBounds);
+        updateAdjustedBounds();
 
         return true;
     }
@@ -314,10 +280,11 @@
 
     public void getBounds(Rect out) {
         if (useCurrentBounds()) {
-            // If we're currently adjusting for IME, we use the adjusted bounds; otherwise,
-            // no need to adjust the output bounds if fullscreen or the docked stack is visible
-            // since it is already what we want to represent to the rest of the system.
-            if (!mContentBounds.isEmpty()) {
+            // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
+            // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
+            // stack is visible since it is already what we want to represent to the rest of the
+            // system.
+            if (!mAdjustedBounds.isEmpty()) {
                 out.set(mAdjustedBounds);
             } else {
                 out.set(mBounds);
@@ -338,39 +305,51 @@
     }
 
     void updateDisplayInfo(Rect bounds) {
-        mUpdateBoundsAfterRotation = false;
-        if (mDisplayContent != null) {
-            for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent);
-            }
-            if (bounds != null) {
-                setBounds(bounds);
-            } else if (mFullscreen) {
-                setBounds(null);
-            } else {
-                mUpdateBoundsAfterRotation = true;
-                mTmpRect2.set(mBounds);
-                final int newRotation = mDisplayContent.getDisplayInfo().rotation;
-                if (mRotation == newRotation) {
-                    setBounds(mTmpRect2);
-                }
+        if (mDisplayContent == null) {
+            return;
+        }
 
-                // If the rotation changes, we'll handle it in updateBoundsAfterRotation
-            }
+        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent);
+        }
+        if (bounds != null) {
+            setBounds(bounds);
+            return;
+        } else if (mFullscreen) {
+            setBounds(null);
+            return;
+        }
+
+        mTmpRect2.set(mBounds);
+        final int newRotation = mDisplayContent.getDisplayInfo().rotation;
+        if (mRotation == newRotation) {
+            setBounds(mTmpRect2);
+        } else {
+            mLastUpdateDisplayInfoRotation = newRotation;
+            updateBoundsAfterRotation();
         }
     }
 
-    /**
-     * Updates the bounds after rotating the screen. We can't handle it in
-     * {@link #updateDisplayInfo} because at that point the configuration might not be fully updated
-     * yet.
-     */
+    void onConfigurationChanged() {
+        mLastConfigChangedRotation = getDisplayInfo().rotation;
+        updateBoundsAfterRotation();
+    }
+
     void updateBoundsAfterRotation() {
-        if (!mUpdateBoundsAfterRotation) {
+        if (mLastConfigChangedRotation != mLastUpdateDisplayInfoRotation) {
+            // We wait for the rotation values after configuration change and display info. update
+            // to be equal before updating the bounds due to rotation change otherwise things might
+            // get out of alignment...
             return;
         }
-        mUpdateBoundsAfterRotation = false;
+
         final int newRotation = getDisplayInfo().rotation;
+
+        if (mRotation == newRotation) {
+            // Nothing to do here if the rotation didn't change
+            return;
+        }
+
         mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
         if (mStackId == DOCKED_STACK_ID) {
             snapDockedStackAfterRotation(mTmpRect2);
@@ -379,8 +358,8 @@
         // Post message to inform activity manager of the bounds change simulating
         // a one-way call. We do this to prevent a deadlock between window manager
         // lock and activity manager lock been held.
-        mService.mH.sendMessage(mService.mH.obtainMessage(
-                RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2));
+        mService.mH.obtainMessage(
+                RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget();
     }
 
     /**
@@ -420,7 +399,7 @@
                 final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
                 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                     final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
-                    if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) {
+                    if (winAnimator.isAnimating() || winAnimator.mWin.mAnimatingExit) {
                         return true;
                     }
                 }
@@ -691,7 +670,7 @@
                 outBounds.top = dockedBounds.bottom + dockDividerWidth;
             }
         }
-        DockedDividerUtils.sanitizeStackBounds(outBounds);
+        DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
     }
 
     /** Resizes all non-docked stacks in the system to either fullscreen or the appropriate size
@@ -802,6 +781,158 @@
         mDisplayContent = null;
     }
 
+    /**
+     * Adjusts the stack bounds if the IME is visible.
+     *
+     * @param imeWin The IME window.
+     */
+    void setAdjustedForIme(WindowState imeWin) {
+        mAdjustedForIme = true;
+        mImeWin = imeWin;
+        updateAdjustedBounds();
+    }
+
+    /**
+     * Resets the adjustment after it got adjusted for the IME.
+     */
+    void resetAdjustedForIme() {
+        mAdjustedForIme = false;
+        mImeWin = null;
+        updateAdjustedBounds();
+    }
+
+    /**
+     * Sets the amount how much we currently minimize our stack.
+     *
+     * @param minimizeAmount The amount, between 0 and 1.
+     * @return Whether the amount has changed and a layout is needed.
+     */
+    boolean setAdjustedForMinimizedDock(float minimizeAmount) {
+        if (minimizeAmount != mMinimizeAmount) {
+            mMinimizeAmount = minimizeAmount;
+            updateAdjustedBounds();
+            return isVisibleForUserLocked();
+        } else {
+            return false;
+        }
+    }
+
+    private boolean adjustForIME(final WindowState imeWin) {
+        final int dockedSide = getDockSide();
+        final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
+        final Rect adjustedBounds = mTmpAdjustedBounds;
+        if (imeWin == null || !dockedTopOrBottom) {
+            return false;
+        }
+
+        final Rect displayContentRect = mTmpRect;
+        final Rect contentBounds = mTmpRect2;
+
+        // Calculate the content bounds excluding the area occupied by IME
+        getDisplayContent().getContentRect(displayContentRect);
+        contentBounds.set(displayContentRect);
+        int imeTop = Math.max(imeWin.getDisplayFrameLw().top, contentBounds.top);
+        imeTop += imeWin.getGivenContentInsetsLw().top;
+        if (contentBounds.bottom > imeTop) {
+            contentBounds.bottom = imeTop;
+        }
+
+        // If content bounds not changing, nothing to do.
+        if (mLastContentBounds.equals(contentBounds)) {
+            return true;
+        }
+
+        // Content bounds changed, need to apply adjustments depending on dock sides.
+        mLastContentBounds.set(contentBounds);
+        adjustedBounds.set(mBounds);
+        final int yOffset = displayContentRect.bottom - contentBounds.bottom;
+
+        if (dockedSide == DOCKED_TOP) {
+            // If this stack is docked on top, we make it smaller so the bottom stack is not
+            // occluded by IME. We shift its bottom up by the height of the IME (capped by
+            // the display content rect). Note that we don't change the task bounds.
+            adjustedBounds.bottom = Math.max(
+                    adjustedBounds.bottom - yOffset, displayContentRect.top);
+        } else {
+            // If this stack is docked on bottom, we shift it up so that it's not occluded by
+            // IME. We try to move it up by the height of the IME window (although the best
+            // we could do is to make the top stack fully collapsed).
+            final int dividerWidth = getDisplayContent().mDividerControllerLocked
+                    .getContentWidth();
+            adjustedBounds.top = Math.max(
+                    adjustedBounds.top - yOffset, displayContentRect.top + dividerWidth);
+            adjustedBounds.bottom = adjustedBounds.top + mBounds.height();
+        }
+        return true;
+    }
+
+    private boolean adjustForMinimizedDockedStack(float minimizeAmount) {
+        final int dockSide = getDockSide();
+        if (dockSide == DOCKED_INVALID && !mTmpAdjustedBounds.isEmpty()) {
+            return false;
+        }
+
+        if (dockSide == DOCKED_TOP) {
+            mService.getStableInsetsLocked(mTmpRect);
+            int topInset = mTmpRect.top;
+            mTmpAdjustedBounds.set(mBounds);
+            mTmpAdjustedBounds.bottom =
+                    (int) (minimizeAmount * topInset + (1 - minimizeAmount) * mBounds.bottom);
+        } else if (dockSide == DOCKED_LEFT) {
+            mTmpAdjustedBounds.set(mBounds);
+            mTmpAdjustedBounds.right =
+                    (int) (minimizeAmount * mDockedStackMinimizeThickness
+                            + (1 - minimizeAmount) * mBounds.right);
+        } else if (dockSide == DOCKED_RIGHT) {
+            mTmpAdjustedBounds.set(mBounds);
+            mTmpAdjustedBounds.left =
+                    (int) (minimizeAmount * (mBounds.right - mDockedStackMinimizeThickness)
+                            + (1 - minimizeAmount) * mBounds.left);
+        }
+        return true;
+    }
+
+    /**
+     * @return the distance in pixels how much the stack gets minimized from it's original size
+     */
+    int getMinimizeDistance() {
+        final int dockSide = getDockSide();
+        if (dockSide == DOCKED_INVALID) {
+            return 0;
+        }
+
+        if (dockSide == DOCKED_TOP) {
+            mService.getStableInsetsLocked(mTmpRect);
+            int topInset = mTmpRect.top;
+            return mBounds.bottom - topInset;
+        } else if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
+            return mBounds.width() - mDockedStackMinimizeThickness;
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Updates the adjustment depending on it's current state.
+     */
+    void updateAdjustedBounds() {
+        boolean adjust = false;
+        if (mMinimizeAmount != 0f) {
+            adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
+        } else if (mAdjustedForIme) {
+            adjust = adjustForIME(mImeWin);
+        }
+        if (!adjust) {
+            mTmpAdjustedBounds.setEmpty();
+            mLastContentBounds.setEmpty();
+        }
+        setAdjustedBounds(mTmpAdjustedBounds, isAdjustedForMinimizedDockedStack());
+    }
+
+    boolean isAdjustedForMinimizedDockedStack() {
+        return mMinimizeAmount != 0f;
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + "mStackId=" + mStackId);
         pw.println(prefix + "mDeferDetach=" + mDeferDetach);
@@ -906,13 +1037,28 @@
         }
 
         for (int i = mTasks.size() - 1; i >= 0; i--) {
-            Task task = mTasks.get(i);
+            final Task task = mTasks.get(i);
             for (int j = task.mAppTokens.size() - 1; j >= 0; j--) {
                 if (!task.mAppTokens.get(j).hidden) {
                     return true;
                 }
             }
         }
+
+        return false;
+    }
+
+    /**
+     * @return true if a the stack is visible for the current in user, ignoring any other visibility
+     *         aspects, and false otherwise
+     */
+    boolean isVisibleForUserLocked() {
+        for (int i = mTasks.size() - 1; i >= 0; i--) {
+            final Task task = mTasks.get(i);
+            if (task.isVisibleForUser()) {
+                return true;
+            }
+        }
         return false;
     }
 
@@ -979,4 +1125,4 @@
     public void getFullScreenBounds(Rect bounds) {
         getDisplayContent().getContentRect(bounds);
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index f8a4d33..38d0711 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -705,7 +705,8 @@
                 }
 
                 orAnimating(mService.getDisplayContentLocked(displayId).animateDimLayers());
-
+                orAnimating(mService.getDisplayContentLocked(displayId).getDockedDividerController()
+                        .animate(mCurrentTime));
                 //TODO (multidisplay): Magnification is supported only for the default display.
                 if (mService.mAccessibilityController != null
                         && displayId == Display.DEFAULT_DISPLAY) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b661786..142715e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -116,7 +116,7 @@
 import android.view.animation.Animation;
 import android.view.inputmethod.InputMethodManagerInternal;
 import android.widget.Toast;
-import com.android.internal.R;
+
 import com.android.internal.app.IAssistScreenshotReceiver;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.FastPrintWriter;
@@ -192,6 +192,8 @@
 import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
+import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
@@ -1354,7 +1356,7 @@
                             + " policyVis=" + w.mPolicyVisibility
                             + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
                             + " attachHid=" + w.mAttachedHidden
-                            + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
+                            + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
                     if (w.mAppToken != null) {
                         Slog.i(TAG_WM, "  mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
                     }
@@ -2057,7 +2059,7 @@
         WindowState replacedWindow = null;
         for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) {
             WindowState candidate = atoken.windows.get(i);
-            if (candidate.mExiting && candidate.mWillReplaceWindow
+            if (candidate.mAnimatingExit && candidate.mWillReplaceWindow
                     && candidate.mAnimateReplacingWindow) {
                 replacedWindow = candidate;
             }
@@ -2131,19 +2133,12 @@
             if (win == null) {
                 return;
             }
-            // We set this here instead of removeWindowLocked because we only want it to be
-            // true when the client has requested we remove the window. In other remove
-            // cases, we have to wait for activity stop to safely remove the window (as the
-            // client may still be using the surface). In this case though, the client has
-            // just dismissed a window (for example a Dialog) and activity stop isn't
-            // necessarily imminent, so we need to know not to wait for it after our
-            // hanimation (if applicable) finishes.
-            win.mClientRemoveRequested = true;
             removeWindowLocked(win);
         }
     }
 
     void removeWindowLocked(WindowState win) {
+        win.mWindowRemovalAllowed = true;
         final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING;
         if (startingWindow) {
             if (DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, "Starting window removed " + win);
@@ -2159,23 +2154,25 @@
 
         win.disposeInputChannel();
 
-        if (DEBUG_APP_TRANSITIONS) Slog.v(
-                TAG_WM, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
-                + " mExiting=" + win.mExiting
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+                "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
+                + " mAnimatingExit=" + win.mAnimatingExit
+                + " mRemoveOnExit=" + win.mRemoveOnExit
+                + " mHasSurface=" + win.mHasSurface
+                + " surfaceShowing=" + win.mWinAnimator.getShown()
                 + " isAnimating=" + win.mWinAnimator.isAnimating()
                 + " app-animation="
                 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
-                + " mWillReplaceWindow="
-                + win.mWillReplaceWindow
+                + " mWillReplaceWindow=" + win.mWillReplaceWindow
                 + " inPendingTransaction="
                 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
-                + " mDisplayFrozen=" + mDisplayFrozen);
+                + " mDisplayFrozen=" + mDisplayFrozen
+                + " callers=" + Debug.getCallers(6));
         // Visibility of the removed window. Will be used later to update orientation later on.
         boolean wasVisible = false;
-        // First, see if we need to run an animation.  If we do, we have
-        // to hold off on removing the window until the animation is done.
-        // If the display is frozen, just remove immediately, since the
-        // animation wouldn't be seen.
+        // First, see if we need to run an animation. If we do, we have to hold off on removing the
+        // window until the animation is done. If the display is frozen, just remove immediately,
+        // since the animation wouldn't be seen.
         if (win.mHasSurface && okToDisplay()) {
             final AppWindowToken appToken = win.mAppToken;
             if (win.mWillReplaceWindow) {
@@ -2183,13 +2180,16 @@
                 // gets added, then we will get rid of this one.
                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is "
                         + "added");
-                win.mExiting = true;
+                // TODO: We are overloading mAnimatingExit flag to prevent the window state from
+                // been removed. We probably need another falg to indicate that window removal
+                // should be deffered vs. overloading the flag that says we are playing an exit
+                // animation.
+                win.mAnimatingExit = true;
                 win.mReplacingRemoveRequested = true;
                 Binder.restoreCallingIdentity(origId);
                 return;
             }
-            // If we are not currently running the exit animation, we
-            // need to see about starting one.
+            // If we are not currently running the exit animation, we need to see about starting one
             wasVisible = win.isWinVisibleLw();
 
             if (win.shouldKeepVisibleDeadAppWindow()) {
@@ -2209,14 +2209,13 @@
                 return;
             }
 
+            final WindowStateAnimator winAnimator = win.mWinAnimator;
             if (wasVisible) {
-                final int transit = (!startingWindow)
-                        ? WindowManagerPolicy.TRANSIT_EXIT
-                        : WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
+                final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
 
                 // Try starting an animation.
-                if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
-                    win.mExiting = true;
+                if (winAnimator.applyAnimationLocked(transit, false)) {
+                    win.mAnimatingExit = true;
                 }
                 //TODO (multidisplay): Magnification is supported only for the default display.
                 if (mAccessibilityController != null
@@ -2224,15 +2223,20 @@
                     mAccessibilityController.onWindowTransitionLocked(win, transit);
                 }
             }
-            final boolean isAnimating = win.mWinAnimator.isAnimating()
-                    && !win.mWinAnimator.isDummyAnimation();
-            // The starting window is the last window in this app token and it isn't animating.
-            // Allow it to be removed now as there is no additional window or animation that will
-            // trigger its removal.
-            final boolean lastWinStartingNotAnimating = startingWindow && appToken!= null
-                    && appToken.allAppWindows.size() == 1 && !isAnimating;
-            if (!lastWinStartingNotAnimating && win.mExiting) {
-                // The exit animation is running... wait for it!
+            final boolean isAnimating =
+                    winAnimator.isAnimating() && !winAnimator.isDummyAnimation();
+            final boolean lastWindowIsStartingWindow = startingWindow && appToken != null
+                    && appToken.allAppWindows.size() == 1;
+            // We delay the removal of a window if it has a showing surface that can be used to run
+            // exit animation and it is marked as exiting.
+            // Also, If isn't the an animating starting window that is the last window in the app.
+            // We allow the removal of the non-animating starting window now as there is no
+            // additional window or animation that will trigger its removal.
+            if (winAnimator.getShown() && win.mAnimatingExit
+                    && (!lastWindowIsStartingWindow || isAnimating)) {
+                // The exit animation is running or should run... wait for it!
+                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
+                        "Not removing " + win + " due to exit animation ");
                 win.mRemoveOnExit = true;
                 win.setDisplayLayoutNeeded();
                 final boolean focusChanged = updateFocusedWindowLocked(
@@ -2262,13 +2266,14 @@
     void removeWindowInnerLocked(WindowState win) {
         if (win.mRemoved) {
             // Nothing to do.
+            if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
+                    "removeWindowInnerLocked: " + win + " Already removed...");
             return;
         }
 
-        for (int i=win.mChildWindows.size()-1; i>=0; i--) {
+        for (int i = win.mChildWindows.size() - 1; i >= 0; i--) {
             WindowState cwin = win.mChildWindows.get(i);
-            Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container "
-                    + win);
+            Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container " + win);
             removeWindowInnerLocked(cwin);
         }
 
@@ -2681,16 +2686,16 @@
                 final boolean usingSavedSurfaceBeforeVisible =
                         oldVisibility != View.VISIBLE && win.isAnimatingWithSavedSurface();
                 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
-                    if (winAnimator.hasSurface() && !win.mExiting
+                    if (winAnimator.hasSurface() && !win.mAnimatingExit
                             && usingSavedSurfaceBeforeVisible) {
                         Slog.d(TAG, "Ignoring layout to invisible when using saved surface " + win);
                     }
                 }
 
-                if (winAnimator.hasSurface() && !win.mExiting
+                if (winAnimator.hasSurface() && !win.mAnimatingExit
                         && !usingSavedSurfaceBeforeVisible) {
                     if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win
-                            + ": mExiting=" + win.mExiting);
+                            + ": mAnimatingExit=" + win.mAnimatingExit);
                     // If we are not currently running the exit animation, we
                     // need to see about starting one.
                     // We don't want to animate visibility of windows which are pending
@@ -2797,16 +2802,16 @@
         }
         if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
             focusMayChange = isDefaultDisplay;
-            win.mExiting = true;
+            win.mAnimatingExit = true;
         } else if (win.mWinAnimator.isAnimating()) {
             // Currently in a hide animation... turn this into
             // an exit.
-            win.mExiting = true;
+            win.mAnimatingExit = true;
         } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
             // If the wallpaper is currently behind this
             // window, we need to change both of them inside
             // of a transaction to avoid artifacts.
-            win.mExiting = true;
+            win.mAnimatingExit = true;
             win.mWinAnimator.mAnimating = true;
         } else {
             if (mInputMethodWindow == win) {
@@ -2842,12 +2847,12 @@
     private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win,
             WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) {
         result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0;
-        if (win.mExiting) {
-            Slog.d(TAG, "relayoutVisibleWindow: " + win + " mExiting=true, mRemoveOnExit="
+        if (win.mAnimatingExit) {
+            Slog.d(TAG, "relayoutVisibleWindow: " + win + " mAnimatingExit=true, mRemoveOnExit="
                     + win.mRemoveOnExit + ", mDestroying=" + win.mDestroying);
 
             winAnimator.cancelExitAnimationForNextAnimationLocked();
-            win.mExiting = false;
+            win.mAnimatingExit = false;
         }
         if (win.mDestroying) {
             win.mDestroying = false;
@@ -2968,6 +2973,8 @@
             // Determine the visible rect to calculate the thumbnail clip
             final WindowState win = atoken.findMainWindow();
             final Rect frame = new Rect(0, 0, width, height);
+            final Rect displayFrame = new Rect(0, 0,
+                    displayInfo.logicalWidth, displayInfo.logicalHeight);
             final Rect insets = new Rect();
             Rect surfaceInsets = null;
             final boolean freeform = win != null && win.inFreeformWorkspace();
@@ -2995,8 +3002,8 @@
                     + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
                     + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
             Animation a = mAppTransition.loadAnimation(lp, transit, enter,
-                    mCurConfiguration.orientation, frame, insets, surfaceInsets, isVoiceInteraction,
-                    freeform, atoken.mTask.mTaskId);
+                    mCurConfiguration.orientation, frame, displayFrame, insets, surfaceInsets,
+                    isVoiceInteraction, freeform, atoken.mTask.mTaskId);
             if (a != null) {
                 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + atoken);
                 final int containingWidth = frame.width();
@@ -3542,23 +3549,20 @@
         }
 
         synchronized(mWindowMap) {
-            final boolean orientationChanged = mCurConfiguration.orientation != config.orientation;
             mCurConfiguration = new Configuration(config);
             if (mWaitingForConfig) {
                 mWaitingForConfig = false;
                 mLastFinishedFreezeSource = "new-config";
             }
-            if (orientationChanged) {
-                updateTaskStackBoundsAfterRotation();
-            }
+            onConfigurationChanged();
             mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
-    private void updateTaskStackBoundsAfterRotation() {
+    private void onConfigurationChanged() {
         for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) {
             final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
-            stack.updateBoundsAfterRotation();
+            stack.onConfigurationChanged();
         }
     }
 
@@ -4153,11 +4157,15 @@
             }
         }
 
-        if (visibilityChanged && visible && !delayed) {
-            // The token was made immediately visible, there will be no entrance animation. We need
-            // to inform the client the enter animation was finished.
-            wtoken.mEnteringAnimation = true;
-            mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(wtoken.token);
+        if (visibilityChanged && !delayed) {
+            if (visible) {
+                // The token was made immediately visible, there will be no entrance animation.
+                // We need to inform the client the enter animation was finished.
+                wtoken.mEnteringAnimation = true;
+                mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(wtoken.token);
+            }
+            getDefaultDisplayContentLocked().getDockedDividerController()
+                    .notifyAppVisibilityChanged(wtoken, visible);
         }
 
         return delayed;
@@ -8124,14 +8132,14 @@
                             for (int i = stacks.size() - 1; i >= 0; --i) {
                                 final TaskStack stack = stacks.get(i);
                                 if (stack.isVisibleLocked()) {
-                                    stack.adjustForIME(imeWin);
+                                    stack.setAdjustedForIme(imeWin);
                                 }
                             }
                         } else {
                             final ArrayList<TaskStack> stacks = displayContent.getStacks();
                             for (int i = stacks.size() - 1; i >= 0; --i) {
                                 final TaskStack stack = stacks.get(i);
-                                stack.adjustForIME(null);
+                                stack.resetAdjustedForIme();
                             }
                         }
                     }
@@ -10333,7 +10341,8 @@
     @Override
     public int getDockedStackSide() {
         synchronized (mWindowMap) {
-            TaskStack dockedStack = getDefaultDisplayContentLocked().getDockedStackLocked();
+            final TaskStack dockedStack = getDefaultDisplayContentLocked()
+                    .getDockedStackVisibleForUserLocked();
             return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
         }
     }
@@ -10417,11 +10426,16 @@
         }
     }
 
-    private void getStableInsetsLocked(Rect outInsets) {
+    void getStableInsetsLocked(Rect outInsets) {
         final DisplayInfo di = getDefaultDisplayInfoLocked();
         mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
     }
 
+    private void getNonDecorInsetsLocked(Rect outInsets) {
+        final DisplayInfo di = getDefaultDisplayInfoLocked();
+        mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
+    }
+
     /**
      * Intersects the specified {@code inOutBounds} with the display frame that excludes the stable
      * inset areas.
@@ -10438,6 +10452,23 @@
         }
     }
 
+    /**
+     * Intersects the specified {@code inOutBounds} with the display frame that excludes
+     * areas that could never be removed in Honeycomb. See
+     * {@link WindowManagerPolicy#getNonDecorInsetsLw}.
+     *
+     * @param inOutBounds The inOutBounds to subtract the inset areas from.
+     */
+    public void subtractNonDecorInsets(Rect inOutBounds) {
+        synchronized (mWindowMap) {
+            getNonDecorInsetsLocked(mTmpRect2);
+            final DisplayInfo di = getDefaultDisplayInfoLocked();
+            mTmpRect.set(0, 0, di.logicalWidth, di.logicalHeight);
+            mTmpRect.inset(mTmpRect2);
+            inOutBounds.intersect(mTmpRect);
+        }
+    }
+
     private MousePositionTracker mMousePositionTracker = new MousePositionTracker();
 
     private static class MousePositionTracker implements PointerEventListener {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0958ad2..f30c8d3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -358,7 +358,7 @@
     boolean mLayoutNeeded;
 
     /** Currently running an exit animation? */
-    boolean mExiting;
+    boolean mAnimatingExit;
 
     /** Currently on the mDestroySurface list? */
     boolean mDestroying;
@@ -387,11 +387,11 @@
     boolean mRemoved;
 
     /**
-     * Has the client requested we remove the window? In this case we know
-     * that we can dispose of it when we wish without further synchronization
-     * with the client
+     * It is save to remove the window and destroy the surface because the client requested removal
+     * or some other higher level component said so (e.g. activity manager).
+     * TODO: We should either have different booleans for the removal reason or use a bit-field.
      */
-    boolean mClientRemoveRequested;
+    boolean mWindowRemovalAllowed;
 
     /**
      * Temp for keeping track of windows that have been removed when
@@ -614,7 +614,7 @@
     @Override
     public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
             Rect osf) {
-        if (mWillReplaceWindow && (mExiting || !mReplacingRemoveRequested)) {
+        if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
             // This window is being replaced and either already got information that it's being
             // removed or we are still waiting for some information. Because of this we don't
             // want to apply any more changes to it, so it remains in this state until new window
@@ -1075,7 +1075,7 @@
      */
     private boolean isVisibleUnchecked() {
         return mHasSurface && mPolicyVisibility && !mAttachedHidden
-                && !mExiting && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
+                && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
     }
 
     /**
@@ -1100,7 +1100,7 @@
         }
         final AppWindowToken atoken = mAppToken;
         final boolean animating = atoken != null && atoken.mAppAnimator.animation != null;
-        return mHasSurface && !mDestroying && !mExiting
+        return mHasSurface && !mDestroying && !mAnimatingExit
                 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
                         || mWinAnimator.mAnimation != null || animating);
@@ -1143,7 +1143,7 @@
         return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
                 && mPolicyVisibility && !mAttachedHidden
                 && (atoken == null || !atoken.hiddenRequested)
-                && !mExiting && !mDestroying;
+                && !mAnimatingExit && !mDestroying;
     }
 
     /**
@@ -1237,7 +1237,7 @@
                 || (atoken == null && mRootToken.hidden)
                 || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
                 || mAttachedHidden
-                || (mExiting && !isAnimatingLw())
+                || (mAnimatingExit && !isAnimatingLw())
                 || mDestroying;
     }
 
@@ -1283,7 +1283,7 @@
      */
     boolean hasMoved() {
         return mHasSurface && (mContentChanged || mMovedByResize)
-                && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay()
+                && !mAnimatingExit && !mWinAnimator.mLastHidden && mService.okToDisplay()
                 && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left)
                 && (mAttachedWindow == null || !mAttachedWindow.hasMoved());
     }
@@ -1438,11 +1438,11 @@
             return;
         }
 
-        if (!mExiting && mAppDied) {
+        if (!mAnimatingExit && mAppDied) {
             // If app died visible, apply a dim over the window to indicate that it's inactive
             mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator);
         } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0
-                && mDisplayContent != null && !mExiting && isDisplayedLw()) {
+                && mDisplayContent != null && !mAnimatingExit && isDisplayedLw()) {
             mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator);
         }
     }
@@ -1467,7 +1467,7 @@
                 win.mAnimateReplacingWindow = false;
                 win.mReplacingRemoveRequested = false;
                 win.mReplacingWindow = null;
-                if (win.mExiting) {
+                if (win.mAnimatingExit) {
                     mService.removeWindowInnerLocked(win);
                 }
             }
@@ -1810,7 +1810,7 @@
     }
 
     boolean isClosing() {
-        return mExiting || (mService.mClosingApps.contains(mAppToken));
+        return mAnimatingExit || (mService.mClosingApps.contains(mAppToken));
     }
 
     boolean isAnimatingWithSavedSurface() {
@@ -2341,8 +2341,8 @@
         }
         pw.print(prefix); pw.print(mWinAnimator); pw.println(":");
         mWinAnimator.dump(pw, prefix + "  ", dumpAll);
-        if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
-            pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
+        if (mAnimatingExit || mRemoveOnExit || mDestroying || mRemoved) {
+            pw.print(prefix); pw.print("mAnimatingExit="); pw.print(mAnimatingExit);
                     pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
                     pw.print(" mDestroying="); pw.print(mDestroying);
                     pw.print(" mRemoved="); pw.println(mRemoved);
@@ -2403,12 +2403,12 @@
     @Override
     public String toString() {
         final CharSequence title = getWindowTag();
-        if (mStringNameCache == null || mLastTitle != title || mWasExiting != mExiting) {
+        if (mStringNameCache == null || mLastTitle != title || mWasExiting != mAnimatingExit) {
             mLastTitle = title;
-            mWasExiting = mExiting;
+            mWasExiting = mAnimatingExit;
             mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
                     + " u" + UserHandle.getUserId(mSession.mUid)
-                    + " " + mLastTitle + (mExiting ? " EXITING}" : "}");
+                    + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}");
         }
         return mStringNameCache;
     }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 84a2c09..0828417 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -29,7 +29,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -375,7 +374,7 @@
 
         // Done animating, clean up.
         if (DEBUG_ANIM) Slog.v(
-            TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
+            TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit
             + ", reportedVisible="
             + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
 
@@ -430,7 +429,7 @@
     void finishExit() {
         if (DEBUG_ANIM) Slog.v(
                 TAG, "finishExit in " + this
-                + ": exiting=" + mWin.mExiting
+                + ": exiting=" + mWin.mAnimatingExit
                 + " remove=" + mWin.mRemoveOnExit
                 + " windowAnimating=" + isWindowAnimating());
 
@@ -460,7 +459,7 @@
             }
         }
 
-        if (!mWin.mExiting) {
+        if (!mWin.mAnimatingExit) {
             return;
         }
 
@@ -475,27 +474,27 @@
 
         mWin.mDestroying = true;
 
+        final boolean hasSurface = hasSurface();
+        if (hasSurface) {
+            hide("finishExit");
+        }
+
         // If we have an app token, we ask it to destroy the surface for us,
         // so that it can take care to ensure the activity has actually stopped
         // and the surface is not still in use. Otherwise we add the service to
         // mDestroySurface and allow it to be processed in our next transaction.
         if (mWin.mAppToken != null) {
-            if (hasSurface()) {
-                hide("finishExit");
-            }
             mWin.mAppToken.destroySurfaces();
         } else {
-            if (hasSurface()) {
+            if (hasSurface) {
                 mService.mDestroySurface.add(mWin);
-                hide("finishExit");
             }
-            mWin.mExiting = false;
             if (mWin.mRemoveOnExit) {
                 mService.mPendingRemove.add(mWin);
                 mWin.mRemoveOnExit = false;
             }
         }
-
+        mWin.mAnimatingExit = false;
         mWallpaperControllerLocked.hideWallpapers(mWin);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 4e1b644..f705df8 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -7,7 +7,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -676,8 +675,10 @@
                     // currently animating... let's do something.
                     final int left = w.mFrame.left;
                     final int top = w.mFrame.top;
+                    final boolean adjustedForMinimizedDockedStack = w.getTask() != null &&
+                            w.getTask().mStack.isAdjustedForMinimizedDockedStack();
                     if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
-                            && !w.isDragResizing()) {
+                            && !w.isDragResizing() && !adjustedForMinimizedDockedStack) {
                         winAnimator.setMoveAnimation(left, top);
                     }
 
@@ -751,7 +752,7 @@
                     }
                     if ((w.isOnScreenIgnoringKeyguard()
                             || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
-                            && !w.mExiting && !w.mDestroying) {
+                            && !w.mAnimatingExit && !w.mDestroying) {
                         if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
                             Slog.v(TAG, "Eval win " + w + ": isDrawn="
                                     + w.isDrawnLw()
@@ -1099,6 +1100,7 @@
 
         processApplicationsAnimatingInPlace(transit);
 
+        mTmpLayerAndToken.token = null;
         handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
         final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
         final int topClosingLayer = mTmpLayerAndToken.layer;
@@ -1111,7 +1113,8 @@
         final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
                 topClosingApp.mAppAnimator;
 
-        mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
+        mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
+                mService.mOpeningApps, mService.mClosingApps);
         mService.mAppTransition.postAnimationCallback();
         mService.mAppTransition.clear();
 
@@ -1181,17 +1184,17 @@
                 int layer = -1;
                 for (int j = 0; j < wtoken.windows.size(); j++) {
                     final WindowState win = wtoken.windows.get(j);
-                    // Clearing the mExiting flag before entering animation. It will be set to true
+                    // Clearing the mAnimatingExit flag before entering animation. It will be set to true
                     // if app window is removed, or window relayout to invisible. We don't want to
                     // clear it out for windows that get replaced, because the animation depends on
                     // the flag to remove the replaced window.
                     //
-                    // We also don't clear the mExiting flag for windows which have the
+                    // We also don't clear the mAnimatingExit flag for windows which have the
                     // mRemoveOnExit flag. This indicates an explicit remove request has been issued
                     // by the client. We should let animation proceed and not clear this flag or
                     // they won't eventually be removed by WindowStateAnimator#finishExit.
                     if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
-                        win.mExiting = false;
+                        win.mAnimatingExit = false;
                     }
                     if (win.mWinAnimator.mAnimLayer > layer) {
                         layer = win.mWinAnimator.mAnimLayer;
@@ -1230,7 +1233,7 @@
             wtoken.deferClearAllDrawn = false;
             // Ensure that apps that are mid-starting are also scheduled to have their
             // starting windows removed after the animation is complete
-            if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
+            if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
                 mService.scheduleRemoveStartingWindowLocked(wtoken);
             }
             mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
diff --git a/core/java/android/view/animation/ClipRectLRAnimation.java b/services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java
similarity index 87%
rename from core/java/android/view/animation/ClipRectLRAnimation.java
rename to services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java
index 8993cd3..0db4c70 100644
--- a/core/java/android/view/animation/ClipRectLRAnimation.java
+++ b/services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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.
@@ -11,12 +11,14 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
 
-package android.view.animation;
+package com.android.server.wm.animation;
 
 import android.graphics.Rect;
+import android.view.animation.ClipRectAnimation;
+import android.view.animation.Transformation;
 
 /**
  * Special case of ClipRectAnimation that animates only the left/right
diff --git a/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java b/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java
new file mode 100644
index 0000000..1f5b1a3
--- /dev/null
+++ b/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java
@@ -0,0 +1,86 @@
+/*
+ * 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.server.wm.animation;
+
+import android.graphics.Rect;
+import android.view.animation.ClipRectAnimation;
+import android.view.animation.Interpolator;
+import android.view.animation.Transformation;
+import android.view.animation.TranslateAnimation;
+
+/**
+ * Special case of ClipRectAnimation that animates only the top/bottom
+ * dimensions of the clip, picking up the other dimensions from whatever is
+ * set on the transform already. In addition to that, information about a vertical translation
+ * animation can be specified so this animation simulates as the clip would be applied after instead
+ * of before applying the translation.
+ */
+public class ClipRectTBAnimation extends ClipRectAnimation {
+
+    private final int mFromTranslateY;
+    private final int mToTranslateY;
+    private final Interpolator mTranslateInterpolator;
+    private float mNormalizedTime;
+
+    /**
+     * Constructor. Passes in 0 for Left/Right parameters of ClipRectAnimation
+     */
+    public ClipRectTBAnimation(int fromT, int fromB, int toT, int toB,
+            int fromTranslateY, int toTranslateY, Interpolator translateInterpolator) {
+        super(0, fromT, 0, fromB, 0, toT, 0, toB);
+        mFromTranslateY = fromTranslateY;
+        mToTranslateY = toTranslateY;
+        mTranslateInterpolator = translateInterpolator;
+    }
+
+    @Override
+    public boolean getTransformation(long currentTime, Transformation outTransformation) {
+
+        // Hack: Because translation animation has a different interpolator, we need to duplicate
+        // code from Animation here and use it to calculate/store the uninterpolated normalized
+        // time.
+        final long startOffset = getStartOffset();
+        final long duration = getDuration();
+        float normalizedTime;
+        if (duration != 0) {
+            normalizedTime = ((float) (currentTime - (getStartTime() + startOffset))) /
+                    (float) duration;
+        } else {
+            // time is a step-change with a zero duration
+            normalizedTime = currentTime < getStartTime() ? 0.0f : 1.0f;
+        }
+        mNormalizedTime = normalizedTime;
+        return super.getTransformation(currentTime, outTransformation);
+    }
+
+    /**
+     * Calculates and sets clip rect on given transformation. It uses existing values
+     * on the Transformation for Left/Right clip parameters.
+     */
+    @Override
+    protected void applyTransformation(float it, Transformation tr) {
+        float translationT = mTranslateInterpolator.getInterpolation(mNormalizedTime);
+        int translation =
+                (int) (mFromTranslateY + (mToTranslateY - mFromTranslateY) * translationT);
+        Rect oldClipRect = tr.getClipRect();
+        tr.setClipRect(oldClipRect.left,
+                mFromRect.top - translation + (int) ((mToRect.top - mFromRect.top) * it),
+                oldClipRect.right,
+                mFromRect.bottom - translation + (int) ((mToRect.bottom - mFromRect.bottom) * it));
+    }
+
+}
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index bb571c3..5e5c6d9 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -17,6 +17,7 @@
     $(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
     $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_HardwarePropertiesManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp \
     $(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \
     $(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \
diff --git a/core/jni/android_os_HardwarePropertiesManager.cpp b/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
similarity index 93%
rename from core/jni/android_os_HardwarePropertiesManager.cpp
rename to services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
index dc1ba48..214d988 100644
--- a/core/jni/android_os_HardwarePropertiesManager.cpp
+++ b/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "HardwarePropertiesManager-JNI"
+#define LOG_TAG "HardwarePropertiesManagerService-JNI"
 
 #include "JNIHelp.h"
 #include "jni.h"
@@ -137,7 +137,7 @@
 
 // ----------------------------------------------------------------------------
 
-static const JNINativeMethod gHardwarePropertiesManagerMethods[] = {
+static const JNINativeMethod gHardwarePropertiesManagerServiceMethods[] = {
     /* name, signature, funcPtr */
     { "nativeInit", "()V",
             (void*) nativeInit },
@@ -149,11 +149,11 @@
             (void*) nativeGetCpuUsages }
 };
 
-int register_android_os_HardwarePropertiesManager(JNIEnv* env) {
+int register_android_server_HardwarePropertiesManagerService(JNIEnv* env) {
     gHardwarePropertiesModule = nullptr;
-    int res = jniRegisterNativeMethods(env, "android/os/HardwarePropertiesManager",
-                                       gHardwarePropertiesManagerMethods,
-                                       NELEM(gHardwarePropertiesManagerMethods));
+    int res = jniRegisterNativeMethods(env, "com/android/server/HardwarePropertiesManagerService",
+                                       gHardwarePropertiesManagerServiceMethods,
+                                       NELEM(gHardwarePropertiesManagerServiceMethods));
     jclass clazz = env->FindClass("android/os/CpuUsageInfo");
     gCpuUsageInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
     gCpuUsageInfoClassInfo.initMethod = GetMethodIDOrDie(env, gCpuUsageInfoClassInfo.clazz,
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index cdd5519..e39445a 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -42,7 +42,7 @@
 static jmethodID method_reportAGpsStatus;
 static jmethodID method_reportNmea;
 static jmethodID method_setEngineCapabilities;
-static jmethodID method_setGpsYearOfHardware;
+static jmethodID method_setGnssYearOfHardware;
 static jmethodID method_xtraDownloadRequest;
 static jmethodID method_reportNiNotification;
 static jmethodID method_requestRefLocation;
@@ -133,11 +133,10 @@
     for (size_t i = 0; i < sGnssSvListSize; i++) {
         GnssSvInfo& info = sGnssSvList[i];
         info.svid = sv_status->sv_list[i].prn;
-        // TODO: implement the correct logic to derive the constellation type
-        // based on PRN ranges.
         if (info.svid >=1 && info.svid <= 32) {
             info.constellation = GNSS_CONSTELLATION_GPS;
         } else {
+            ALOGD("Unknown constellation type with Svid = %d.", info.svid);
             info.constellation = GNSS_CONSTELLATION_UNKNOWN;
         }
         info.snr = sv_status->sv_list[i].snr;
@@ -198,10 +197,10 @@
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
 }
 
-static void set_system_info_callback(const GpsSystemInfo* info) {
+static void set_system_info_callback(const GnssSystemInfo* info) {
     ALOGD("set_system_info_callback: year_of_hw=%d\n", info->year_of_hw);
     JNIEnv* env = AndroidRuntime::getJNIEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setGpsYearOfHardware,
+    env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
                         info->year_of_hw);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
 }
@@ -536,7 +535,7 @@
     method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
     method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
     method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
-    method_setGpsYearOfHardware = env->GetMethodID(clazz, "setGpsYearOfHardware", "(I)V");
+    method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
     method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
     method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
             "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
@@ -1074,7 +1073,9 @@
 template<>
 const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
 template<>
-const char *const JavaMethodHelper<int>::signature_ = "(I)V";
+const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
+template<>
+const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
 template<>
 const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
 template<>
@@ -1092,36 +1093,22 @@
     JavaObject object(env, "android/location/GnssClock");
     GpsClockFlags flags = clock->flags;
 
-    SET_IF(GPS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
+    SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
     SET(Type, clock->type);
     SET(TimeInNs, clock->time_ns);
-    SET_IF(GPS_CLOCK_HAS_TIME_UNCERTAINTY,
+    SET_IF(GNSS_CLOCK_HAS_TIME_UNCERTAINTY,
            TimeUncertaintyInNs,
            clock->time_uncertainty_ns);
-    SET_IF(GPS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
-    SET_IF(GPS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
-    SET_IF(GPS_CLOCK_HAS_BIAS_UNCERTAINTY,
+    SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
+    SET_IF(GNSS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
+    SET_IF(GNSS_CLOCK_HAS_BIAS_UNCERTAINTY,
            BiasUncertaintyInNs,
            clock->bias_uncertainty_ns);
-    SET_IF(GPS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
-    SET_IF(GPS_CLOCK_HAS_DRIFT_UNCERTAINTY,
+    SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
+    SET_IF(GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY,
            DriftUncertaintyInNsPerSec,
            clock->drift_uncertainty_nsps);
 
-    /*
-    if (flags & GPS_CLOCK_TYPE_LOCAL_HW_TIME) {
-        if (size == sizeof(GnssClock)) {
-            jmethodID setterMethod =
-                    env->GetMethodID(gpsClockClass,
-                                     "setTimeOfLastHwClockDiscontinuityInNs",
-                                     longSignature);
-            env->CallVoidMethod(gpsClockObject,
-                                setterMethod,
-                                reinterpret_cast<GnssClock*>(clock)->time_of_last_hw_clock_discontinuity_ns);
-        }
-    }
-    */
-
     return object.get();
 }
 
@@ -1129,25 +1116,23 @@
     JavaObject object(env, "android/location/GnssClock");
     GpsClockFlags flags = clock->flags;
 
-    SET_IF(GPS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
-    SET(Type, clock->type);
+    SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
+    SET(Type, static_cast<uint8_t>(GPS_CLOCK_TYPE_LOCAL_HW_TIME));
     SET(TimeInNs, clock->time_ns);
-    SET_IF(GPS_CLOCK_HAS_TIME_UNCERTAINTY,
+    SET_IF(GNSS_CLOCK_HAS_TIME_UNCERTAINTY,
            TimeUncertaintyInNs,
            clock->time_uncertainty_ns);
-    SET_IF(GPS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
-    SET_IF(GPS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
-    SET_IF(GPS_CLOCK_HAS_BIAS_UNCERTAINTY,
+    SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
+    SET_IF(GNSS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
+    SET_IF(GNSS_CLOCK_HAS_BIAS_UNCERTAINTY,
            BiasUncertaintyInNs,
            clock->bias_uncertainty_ns);
-    SET_IF(GPS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
-    SET_IF(GPS_CLOCK_HAS_DRIFT_UNCERTAINTY,
+    SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
+    SET_IF(GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY,
            DriftUncertaintyInNsPerSec,
            clock->drift_uncertainty_nsps);
 
-    SET_IF(GPS_CLOCK_TYPE_LOCAL_HW_TIME,
-           TimeOfLastHwClockDiscontinuityInNs,
-           clock->time_of_last_hw_clock_discontinuity_ns);
+    SET(HardwareClockDiscontinuityCount, clock->hw_clock_discontinuity_count);
 
     return object.get();
 }
@@ -1156,12 +1141,18 @@
                                          GpsMeasurement* measurement) {
     JavaObject object(env, "android/location/GnssMeasurement");
     GpsMeasurementFlags flags = measurement->flags;
-
     SET(Svid, static_cast<int16_t>(measurement->prn));
+    if (measurement->prn >= 1 || measurement->prn <= 32) {
+        SET(ConstellationType, static_cast<uint8_t>(GNSS_CONSTELLATION_GPS));
+    } else {
+        ALOGD("Unknown constellation type with Svid = %d.", measurement->prn);
+        SET(ConstellationType,
+            static_cast<uint8_t>(GNSS_CONSTELLATION_UNKNOWN));
+    }
     SET(TimeOffsetInNs, measurement->time_offset_ns);
     SET(State, measurement->state);
-    SET(ReceivedGpsTowInNs, measurement->received_gps_tow_ns);
-    SET(ReceivedGpsTowUncertaintyInNs,
+    SET(ReceivedSvTimeInNs, measurement->received_gps_tow_ns);
+    SET(ReceivedSvTimeUncertaintyInNs,
         measurement->received_gps_tow_uncertainty_ns);
     SET(Cn0InDbHz, measurement->c_n0_dbhz);
     SET(PseudorangeRateInMetersPerSec, measurement->pseudorange_rate_mps);
@@ -1171,57 +1162,57 @@
     SET(AccumulatedDeltaRangeInMeters, measurement->accumulated_delta_range_m);
     SET(AccumulatedDeltaRangeUncertaintyInMeters,
         measurement->accumulated_delta_range_uncertainty_m);
-    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE,
+    SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE,
            PseudorangeInMeters,
            measurement->pseudorange_m);
-    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
            PseudorangeUncertaintyInMeters,
            measurement->pseudorange_uncertainty_m);
-    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE,
+    SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE,
            CodePhaseInChips,
            measurement->code_phase_chips);
-    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
            CodePhaseUncertaintyInChips,
            measurement->code_phase_uncertainty_chips);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
            CarrierFrequencyInHz,
            measurement->carrier_frequency_hz);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_CYCLES,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES,
            CarrierCycles,
            measurement->carrier_cycles);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE,
            CarrierPhase,
            measurement->carrier_phase);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
            CarrierPhaseUncertainty,
            measurement->carrier_phase_uncertainty);
     SET(LossOfLock, measurement->loss_of_lock);
-    SET_IF(GPS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
-    SET_IF(GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
+    SET_IF(GNSS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
+    SET_IF(GNSS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
            TimeFromLastBitInMs,
            measurement->time_from_last_bit_ms);
-    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT,
+    SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT,
            DopplerShiftInHz,
            measurement->doppler_shift_hz);
-    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
            DopplerShiftUncertaintyInHz,
            measurement->doppler_shift_uncertainty_hz);
     SET(MultipathIndicator, measurement->multipath_indicator);
-    SET_IF(GPS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
-    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION,
+    SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
+    SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION,
            ElevationInDeg,
            measurement->elevation_deg);
-    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
            ElevationUncertaintyInDeg,
            measurement->elevation_uncertainty_deg);
-    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH,
+    SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH,
            AzimuthInDeg,
            measurement->azimuth_deg);
-    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
            AzimuthUncertaintyInDeg,
            measurement->azimuth_uncertainty_deg);
     SET(UsedInFix,
-        (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
+        (flags & GNSS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
 
     return object.get();
 }
@@ -1232,11 +1223,12 @@
     GpsMeasurementFlags flags = measurement->flags;
 
     SET(Svid, measurement->svid);
+    SET(ConstellationType, measurement->constellation);
     SET(TimeOffsetInNs, measurement->time_offset_ns);
     SET(State, measurement->state);
-    SET(ReceivedGpsTowInNs, measurement->received_gps_tow_ns);
-    SET(ReceivedGpsTowUncertaintyInNs,
-        measurement->received_gps_tow_uncertainty_ns);
+    SET(ReceivedSvTimeInNs, measurement->received_sv_time_in_ns);
+    SET(ReceivedSvTimeUncertaintyInNs,
+        measurement->received_sv_time_uncertainty_in_ns);
     SET(Cn0InDbHz, measurement->c_n0_dbhz);
     SET(PseudorangeRateInMetersPerSec, measurement->pseudorange_rate_mps);
     SET(PseudorangeRateUncertaintyInMetersPerSec,
@@ -1245,62 +1237,56 @@
     SET(AccumulatedDeltaRangeInMeters, measurement->accumulated_delta_range_m);
     SET(AccumulatedDeltaRangeUncertaintyInMeters,
         measurement->accumulated_delta_range_uncertainty_m);
-    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE,
+    SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE,
            PseudorangeInMeters,
            measurement->pseudorange_m);
-    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
            PseudorangeUncertaintyInMeters,
            measurement->pseudorange_uncertainty_m);
-    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE,
+    SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE,
            CodePhaseInChips,
            measurement->code_phase_chips);
-    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
            CodePhaseUncertaintyInChips,
            measurement->code_phase_uncertainty_chips);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
            CarrierFrequencyInHz,
            measurement->carrier_frequency_hz);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_CYCLES,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES,
            CarrierCycles,
            measurement->carrier_cycles);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE,
            CarrierPhase,
            measurement->carrier_phase);
-    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
            CarrierPhaseUncertainty,
            measurement->carrier_phase_uncertainty);
-    SET(LossOfLock, measurement->loss_of_lock);
-    SET_IF(GPS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
-    SET_IF(GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
+    SET_IF(GNSS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
+    SET_IF(GNSS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
            TimeFromLastBitInMs,
            measurement->time_from_last_bit_ms);
-    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT,
+    SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT,
            DopplerShiftInHz,
            measurement->doppler_shift_hz);
-    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
            DopplerShiftUncertaintyInHz,
            measurement->doppler_shift_uncertainty_hz);
     SET(MultipathIndicator, measurement->multipath_indicator);
-    SET_IF(GPS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
-    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION,
+    SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
+    SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION,
            ElevationInDeg,
            measurement->elevation_deg);
-    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
            ElevationUncertaintyInDeg,
            measurement->elevation_uncertainty_deg);
-    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH,
+    SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH,
            AzimuthInDeg,
            measurement->azimuth_deg);
-    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
+    SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
            AzimuthUncertaintyInDeg,
            measurement->azimuth_uncertainty_deg);
     SET(UsedInFix,
-        (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
-
-    SET(PseudorangeRateCarrierInMetersPerSec,
-        measurement->pseudorange_rate_carrier_mps);
-    SET(PseudorangeRateCarrierUncertaintyInMetersPerSec,
-        measurement->pseudorange_rate_carrier_uncertainty_mps);
+        (flags & GNSS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
 
     return object.get();
 }
@@ -1480,8 +1466,18 @@
         return NULL;
     }
     JavaObject object(env, "android/location/GnssNavigationMessage");
-    SET(Type, message->type);
     SET(Svid, static_cast<int16_t>(message->prn));
+    if (message->prn >=1 && message->prn <= 32) {
+        SET(ConstellationType, static_cast<uint8_t>(GNSS_CONSTELLATION_GPS));
+        // Legacy driver doesn't set the higher byte to constellation type
+        // correctly. Set the higher byte to 'GPS'.
+        SET(Type, static_cast<int16_t>(message->type | 0x0100));
+    } else {
+        ALOGD("Unknown constellation type with Svid = %d.", message->prn);
+        SET(ConstellationType,
+            static_cast<uint8_t>(GNSS_CONSTELLATION_UNKNOWN));
+        SET(Type, static_cast<int16_t>(GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN));
+    }
     SET(MessageId, message->message_id);
     SET(SubmessageId, message->submessage_id);
     object.callSetter("setData", data, dataLength);
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index ef5c56c..be99673 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -44,6 +44,7 @@
 int register_android_server_tv_TvInputHal(JNIEnv* env);
 int register_android_server_PersistentDataBlockService(JNIEnv* env);
 int register_android_server_Watchdog(JNIEnv* env);
+int register_android_server_HardwarePropertiesManagerService(JNIEnv* env);
 };
 
 using namespace android;
@@ -83,6 +84,7 @@
     register_android_server_tv_TvInputHal(env);
     register_android_server_PersistentDataBlockService(env);
     register_android_server_Watchdog(env);
+    register_android_server_HardwarePropertiesManagerService(env);
 
 
     return JNI_VERSION_1_4;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ac972a9..c854573 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -488,6 +488,7 @@
         MmsServiceBroker mmsService = null;
         EntropyMixer entropyMixer = null;
         VrManagerService vrManagerService = null;
+        HardwarePropertiesManagerService hardwarePropertiesService = null;
 
         boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
         boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
@@ -962,6 +963,17 @@
                     Slog.e(TAG, "Failure starting SerialService", e);
                 }
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+
+                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
+                        "StartHardwarePropertiesManagerService");
+                try {
+                    hardwarePropertiesService = new HardwarePropertiesManagerService(context);
+                    ServiceManager.addService(Context.HARDWARE_PROPERTIES_SERVICE,
+                            hardwarePropertiesService);
+                } catch (Throwable e) {
+                    Slog.e(TAG, "Failure starting HardwarePropertiesManagerService", e);
+                }
+                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
             mSystemServiceManager.startService(TwilightService.class);
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 61f2c8a..2a90c60 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -24,6 +24,7 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.LinkProperties.ProvisioningChange;
+import android.net.ProxyInfo;
 import android.net.RouteInfo;
 import android.net.StaticIpConfiguration;
 import android.net.dhcp.DhcpClient;
@@ -31,6 +32,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -64,6 +66,9 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
+    private static final boolean NO_CALLBACKS = false;
+    private static final boolean SEND_CALLBACKS = true;
+
     // For message logging.
     private static final Class[] sMessageClasses = { IpManager.class, DhcpClient.class };
     private static final SparseArray<String> sWhatToString =
@@ -104,6 +109,35 @@
         public void onQuit() {}
     }
 
+    public static class WaitForProvisioningCallback extends Callback {
+        private LinkProperties mCallbackLinkProperties;
+
+        public LinkProperties waitForProvisioning() {
+            synchronized (this) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {}
+                return mCallbackLinkProperties;
+            }
+        }
+
+        @Override
+        public void onProvisioningSuccess(LinkProperties newLp) {
+            synchronized (this) {
+                mCallbackLinkProperties = newLp;
+                notify();
+            }
+        }
+
+        @Override
+        public void onProvisioningFailure(LinkProperties newLp) {
+            synchronized (this) {
+                mCallbackLinkProperties = null;
+                notify();
+            }
+        }
+    }
+
     /**
      * This class encapsulates parameters to be passed to
      * IpManager#startProvisioning(). A defensive copy is made by IpManager
@@ -168,6 +202,8 @@
     private static final int EVENT_PRE_DHCP_ACTION_COMPLETE = 4;
     // Sent by NetlinkTracker to communicate netlink events.
     private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 5;
+    private static final int CMD_UPDATE_TCP_BUFFER_SIZES = 6;
+    private static final int CMD_UPDATE_HTTP_PROXY = 7;
 
     private static final int MAX_LOG_RECORDS = 1000;
 
@@ -189,10 +225,12 @@
     /**
      * Non-final member variables accessed only from within our StateMachine.
      */
+    private ProvisioningConfiguration mConfiguration;
     private IpReachabilityMonitor mIpReachabilityMonitor;
     private DhcpClient mDhcpClient;
     private DhcpResults mDhcpResults;
-    private ProvisioningConfiguration mConfiguration;
+    private String mTcpBufferSizes;
+    private ProxyInfo mHttpProxy;
 
     /**
      * Member variables accessed both from within the StateMachine thread
@@ -301,6 +339,26 @@
         sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
     }
 
+    /**
+     * Set the TCP buffer sizes to use.
+     *
+     * This may be called, repeatedly, at any time before or after a call to
+     * #startProvisioning(). The setting is cleared upon calling #stop().
+     */
+    public void setTcpBufferSizes(String tcpBufferSizes) {
+        sendMessage(CMD_UPDATE_TCP_BUFFER_SIZES, tcpBufferSizes);
+    }
+
+    /**
+     * Set the HTTP Proxy configuration to use.
+     *
+     * This may be called, repeatedly, at any time before or after a call to
+     * #startProvisioning(). The setting is cleared upon calling #stop().
+     */
+    public void setHttpProxy(ProxyInfo proxyInfo) {
+        sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo);
+    }
+
     public LinkProperties getLinkProperties() {
         synchronized (mLock) {
             return new LinkProperties(mLinkProperties);
@@ -344,8 +402,10 @@
     // assigned to the interface, etc.
     private void resetLinkProperties() {
         mNetlinkTracker.clearLinkProperties();
-        mDhcpResults = null;
         mConfiguration = null;
+        mDhcpResults = null;
+        mTcpBufferSizes = "";
+        mHttpProxy = null;
 
         synchronized (mLock) {
             mLinkProperties = new LinkProperties();
@@ -502,13 +562,33 @@
             newLp.setDomains(mDhcpResults.domains);
         }
 
+        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
+        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
+            newLp.setTcpBufferSizes(mTcpBufferSizes);
+        }
+        if (mHttpProxy != null) {
+            newLp.setHttpProxy(mHttpProxy);
+        }
+
         if (VDBG) {
             Log.d(mTag, "newLp{" + newLp + "}");
         }
-
         return newLp;
     }
 
+    // Returns false if we have lost provisioning, true otherwise.
+    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
+        final LinkProperties newLp = assembleLinkProperties();
+        if (linkPropertiesUnchanged(newLp)) {
+            return true;
+        }
+        final ProvisioningChange delta = setLinkProperties(newLp);
+        if (sendCallbacks) {
+            dispatchCallback(delta, newLp);
+        }
+        return (delta != ProvisioningChange.LOST_PROVISIONING);
+    }
+
     private void clearIPv4Address() {
         try {
             final InterfaceConfiguration ifcg = new InterfaceConfiguration();
@@ -587,7 +667,17 @@
                     break;
 
                 case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    setLinkProperties(assembleLinkProperties());
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_TCP_BUFFER_SIZES:
+                    mTcpBufferSizes = (String) msg.obj;
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_HTTP_PROXY:
+                    mHttpProxy = (ProxyInfo) msg.obj;
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
                     break;
 
                 case DhcpClient.CMD_ON_QUIT:
@@ -718,18 +808,23 @@
                     }
                     break;
 
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED: {
-                    final LinkProperties newLp = assembleLinkProperties();
-                    if (linkPropertiesUnchanged(newLp)) {
-                        break;
-                    }
-                    final ProvisioningChange delta = setLinkProperties(newLp);
-                    dispatchCallback(delta, newLp);
-                    if (delta == ProvisioningChange.LOST_PROVISIONING) {
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
                         transitionTo(mStoppedState);
                     }
                     break;
-                }
+
+                case CMD_UPDATE_TCP_BUFFER_SIZES:
+                    mTcpBufferSizes = (String) msg.obj;
+                    // This cannot possibly change provisioning state.
+                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_HTTP_PROXY:
+                    mHttpProxy = (ProxyInfo) msg.obj;
+                    // This cannot possibly change provisioning state.
+                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
+                    break;
 
                 case DhcpClient.CMD_PRE_DHCP_ACTION:
                     if (VDBG) { Log.d(mTag, "onPreDhcpAction()"); }
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 577c3a1..c786036 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -58,7 +58,7 @@
                 .setMinimumLatency(runFromMillis)
                 .setPersisted(true)
                 .build();
-        final JobStatus ts = new JobStatus(task, SOME_UID, null, -1);
+        final JobStatus ts = JobStatus.createFromJobInfo(task, SOME_UID, null, -1);
         mTaskStoreUnderTest.add(ts);
         Thread.sleep(IO_WAIT);
         // Manually load tasks from xml file.
@@ -91,8 +91,8 @@
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
                 .setPersisted(true)
                 .build();
-        final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID, null, -1);
-        final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID, null, -1);
+        final JobStatus taskStatus1 = JobStatus.createFromJobInfo(task1, SOME_UID, null, -1);
+        final JobStatus taskStatus2 = JobStatus.createFromJobInfo(task2, SOME_UID, null, -1);
         mTaskStoreUnderTest.add(taskStatus1);
         mTaskStoreUnderTest.add(taskStatus2);
         Thread.sleep(IO_WAIT);
@@ -140,7 +140,7 @@
         extras.putInt("into", 3);
         b.setExtras(extras);
         final JobInfo task = b.build();
-        JobStatus taskStatus = new JobStatus(task, SOME_UID, null, -1);
+        JobStatus taskStatus = JobStatus.createFromJobInfo(task, SOME_UID, null, -1);
 
         mTaskStoreUnderTest.add(taskStatus);
         Thread.sleep(IO_WAIT);
@@ -157,7 +157,8 @@
                 .setPeriodic(10000L)
                 .setRequiresCharging(true)
                 .setPersisted(true);
-        JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, "com.google.android.gms", 0);
+        JobStatus taskStatus = JobStatus.createFromJobInfo(b.build(), SOME_UID,
+                "com.google.android.gms", 0);
 
         mTaskStoreUnderTest.add(taskStatus);
         Thread.sleep(IO_WAIT);
@@ -178,7 +179,7 @@
                 .setPeriodic(5*60*60*1000, 1*60*60*1000)
                 .setRequiresCharging(true)
                 .setPersisted(true);
-        JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, null, -1);
+        JobStatus taskStatus = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1);
 
         mTaskStoreUnderTest.add(taskStatus);
         Thread.sleep(IO_WAIT);
@@ -203,7 +204,8 @@
                 SystemClock.elapsedRealtime() + (TWO_HOURS * ONE_HOUR) + TWO_HOURS;  // > period+flex
         final long invalidEarlyRuntimeElapsedMillis =
                 invalidLateRuntimeElapsedMillis - TWO_HOURS;  // Early is (late - period).
-        final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage", 0 /* sourceUserId */,
+        final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage",
+                0 /* sourceUserId */,
                 invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis);
 
         mTaskStoreUnderTest.add(js);
@@ -229,7 +231,7 @@
                 .setOverrideDeadline(5000)
                 .setPriority(42)
                 .setPersisted(true);
-        final JobStatus js = new JobStatus(b.build(), SOME_UID, null, -1);
+        final JobStatus js = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1);
         mTaskStoreUnderTest.add(js);
         Thread.sleep(IO_WAIT);
         final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
@@ -245,12 +247,12 @@
         JobInfo.Builder b = new Builder(42, mComponent)
                 .setOverrideDeadline(10000)
                 .setPersisted(false);
-        JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID, null, -1);
+        JobStatus jsNonPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1);
         mTaskStoreUnderTest.add(jsNonPersisted);
         b = new Builder(43, mComponent)
                 .setOverrideDeadline(10000)
                 .setPersisted(true);
-        JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID, null, -1);
+        JobStatus jsPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1);
         mTaskStoreUnderTest.add(jsPersisted);
         Thread.sleep(IO_WAIT);
         final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
diff --git a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
index 31182fc..f1fe346 100644
--- a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -25,7 +25,6 @@
 import org.mockito.MockitoAnnotations;
 
 import android.app.Notification;
-import android.os.Handler;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.test.AndroidTestCase;
@@ -55,14 +54,13 @@
         UserHandle user = UserHandle.ALL;
 
         mHelper = new RankingHelper(getContext(), handler, mUsageStats,
-                new String[] {TopicImportanceExtractor.class.getName()});
+                new String[] {ImportanceExtractor.class.getName()});
 
         mNotiGroupGSortA = new Notification.Builder(getContext())
                 .setContentTitle("A")
                 .setGroup("G")
                 .setSortKey("A")
                 .setWhen(1205)
-                .setTopic(new Notification.Topic("A", "a"))
                 .build();
         mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortA, user));
@@ -72,7 +70,6 @@
                 .setGroup("G")
                 .setSortKey("B")
                 .setWhen(1200)
-                .setTopic(new Notification.Topic("A", "a"))
                 .build();
         mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortB, user));
@@ -80,7 +77,6 @@
         mNotiNoGroup = new Notification.Builder(getContext())
                 .setContentTitle("C")
                 .setWhen(1201)
-                .setTopic(new Notification.Topic("C", "c"))
                 .build();
         mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, 0, mNotiNoGroup, user));
@@ -88,7 +84,6 @@
         mNotiNoGroup2 = new Notification.Builder(getContext())
                 .setContentTitle("D")
                 .setWhen(1202)
-                .setTopic(new Notification.Topic("D", "d"))
                 .build();
         mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, 0, mNotiNoGroup2, user));
@@ -97,7 +92,6 @@
                 .setContentTitle("E")
                 .setWhen(1201)
                 .setSortKey("A")
-                .setTopic(new Notification.Topic("E", "e"))
                 .build();
         mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, 0, mNotiNoGroupSortA, user));
@@ -152,26 +146,4 @@
         ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
         mHelper.sort(notificationList);
     }
-
-    @SmallTest
-    public void testTopicImportanceExtractor() throws Exception {
-        mHelper.setImportance("package", 0, new Notification.Topic("A", "a"), IMPORTANCE_MAX);
-        // There is no B. There never was a b. Moving on...
-        mHelper.setImportance("package", 0, new Notification.Topic("C", "c"), IMPORTANCE_HIGH);
-        mHelper.setImportance("package", 0, new Notification.Topic("D", "d"), IMPORTANCE_LOW);
-        // watch out: different package.
-        mHelper.setImportance("package2", 0, new Notification.Topic("E", "e"), IMPORTANCE_NONE);
-
-        TopicImportanceExtractor validator = mHelper.findExtractor(TopicImportanceExtractor.class);
-        validator.process(mRecordGroupGSortA);
-        validator.process(mRecordGroupGSortB);
-        validator.process(mRecordNoGroup);
-        validator.process(mRecordNoGroup2);
-        validator.process(mRecordNoGroupSortA);
-        assertTrue(mRecordGroupGSortA.getTopicImportance() == IMPORTANCE_MAX);
-        assertTrue(mRecordGroupGSortB.getTopicImportance() == IMPORTANCE_MAX);
-        assertTrue(mRecordNoGroup.getTopicImportance() == IMPORTANCE_HIGH);
-        assertTrue(mRecordNoGroup2.getTopicImportance() == IMPORTANCE_LOW);
-        assertTrue(mRecordNoGroupSortA.getTopicImportance() == IMPORTANCE_UNSPECIFIED);
-    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index cde47bd..b4c4bf8 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -198,6 +198,7 @@
                     return STATUS_ERROR;
                 }
                 modelData.setHandle(handle[0]);
+                modelData.setLoaded();
             }
             modelData.setCallback(callback);
             modelData.setRecognitionConfig(recognitionConfig);
@@ -346,7 +347,7 @@
                 return STATUS_ERROR;
             }
 
-            if (currentCallback == null || !modelData.modelStarted()) {
+            if (currentCallback == null || !modelData.isModelStarted()) {
                 // startRecognition hasn't been called or it failed.
                 Slog.w(TAG, "Attempting stopRecognition without a successful startRecognition");
                 return STATUS_ERROR;
@@ -451,7 +452,7 @@
 
             // Stop all generic recognition models.
             for (ModelData model : mGenericModelDataMap.values()) {
-                if (model.modelStarted()) {
+                if (model.isModelStarted()) {
                     int status = stopGenericRecognitionLocked(model,
                             false /* do not notify for synchronous calls */);
                     if (status != STATUS_OK) {
@@ -970,7 +971,7 @@
             }
             for (UUID modelId : mGenericModelDataMap.keySet()) {
                 ModelData modelData = mGenericModelDataMap.get(modelId);
-                if (modelData.modelStarted()) {
+                if (modelData.isModelStarted()) {
                     mRecognitionRunning = true;
                     return mRecognitionRunning;
                 }
@@ -1001,7 +1002,6 @@
         // to SoundModel.TYPE_UNKNOWN;
         private int mModelType = SoundModel.TYPE_UNKNOWN;
         private IRecognitionStatusCallback mCallback = null;
-        private SoundModel mSoundModel = null;
         private RecognitionConfig mRecognitionConfig = null;
 
 
@@ -1026,8 +1026,7 @@
         }
 
         synchronized boolean isModelLoaded() {
-            return (mModelState == MODEL_LOADED || mModelState == MODEL_STARTED) &&
-                    mSoundModel != null;
+            return (mModelState == MODEL_LOADED || mModelState == MODEL_STARTED);
         }
 
         synchronized void setStarted() {
@@ -1038,13 +1037,16 @@
             mModelState = MODEL_LOADED;
         }
 
-        synchronized boolean modelStarted() {
+        synchronized void setLoaded() {
+            mModelState = MODEL_LOADED;
+        }
+
+        synchronized boolean isModelStarted() {
             return mModelState == MODEL_STARTED;
         }
 
         synchronized void clearState() {
             mModelState = MODEL_NOTLOADED;
-            mSoundModel = null;
             mModelHandle = INVALID_VALUE;
         }
 
diff --git a/tests/SoundTriggerTestApp/res/layout/main.xml b/tests/SoundTriggerTestApp/res/layout/main.xml
index 5ecc770..702be49 100644
--- a/tests/SoundTriggerTestApp/res/layout/main.xml
+++ b/tests/SoundTriggerTestApp/res/layout/main.xml
@@ -66,6 +66,7 @@
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:padding="20dp"
+        android:checkedButton="@+id/model_one"
         android:orientation="vertical">
    <RadioButton android:id="@+id/model_one"
         android:layout_width="wrap_content"
@@ -84,15 +85,21 @@
         android:onClick="onRadioButtonClicked"/>
 </RadioGroup>
 
-    <TextView
-        android:id="@+id/console"
-        android:gravity="left"
+<ScrollView
+       android:id="@+id/scroller_id"
+       android:layout_width="fill_parent"
+       android:layout_height="wrap_content"
+       android:scrollbars="vertical"
+       android:fillViewport="true">
+
+      <TextView
+         android:id="@+id/console"
         android:paddingTop="20pt"
         android:layout_height="fill_parent"
-        android:layout_width="match_parent"
-        android:maxLines="40"
+        android:layout_width="fill_parent"
         android:textSize="14dp"
-        android:scrollbars = "vertical"
+        android:layout_weight="1.0"
         android:text="@string/none">
      </TextView>
+</ScrollView>
 </LinearLayout>
diff --git a/tests/SoundTriggerTestApp/res/values/strings.xml b/tests/SoundTriggerTestApp/res/values/strings.xml
index 5f0fb1d..b4ca71b 100644
--- a/tests/SoundTriggerTestApp/res/values/strings.xml
+++ b/tests/SoundTriggerTestApp/res/values/strings.xml
@@ -24,5 +24,5 @@
     <string name="model_one">Model One</string>
     <string name="model_two">Model Two</string>
     <string name="model_three">Model Three</string>
-    <string name="none">Debug messages appear here:</string>
+    <string name="none">Debug messages appear here:\n</string>
 </resources>
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
index 96a6966..3149783 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 import android.view.View;
 import android.widget.RadioButton;
+import android.widget.ScrollView;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -52,6 +53,7 @@
 
     private TextView mDebugView = null;
     private int mSelectedModelId = 1;
+    private ScrollView mScrollView = null;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -59,6 +61,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         mDebugView = (TextView) findViewById(R.id.console);
+        mScrollView = (ScrollView) findViewById(R.id.scroller_id);
         mDebugView.setText(mDebugView.getText(), TextView.BufferType.EDITABLE);
         mDebugView.setMovementMethod(new ScrollingMovementMethod());
         mSoundTriggerUtil = new SoundTriggerUtil(this);
@@ -68,6 +71,18 @@
     private void postMessage(String msg) {
         Log.i(TAG, "Posted: " + msg);
         ((Editable) mDebugView.getText()).append(msg + "\n");
+        if ((mDebugView.getMeasuredHeight() - mScrollView.getScrollY()) <=
+                (mScrollView.getHeight() + mDebugView.getLineHeight())) {
+            scrollToBottom();
+        }
+    }
+
+    private void scrollToBottom() {
+        mScrollView.post(new Runnable() {
+            public void run() {
+                mScrollView.smoothScrollTo(0, mDebugView.getBottom());
+            }
+        });
     }
 
     private UUID getSelectedUuid() {
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 46de201..9ac4dbf 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -162,78 +162,6 @@
             }
         },
 
-        new Test("with topic Hello") {
-            public void run() {
-                Notification.BigTextStyle bigText = new Notification.BigTextStyle();
-                bigText.bigText("FgBHreherhethethethe\ntwetwrterter\netetweterteryetry");
-                Notification n = new Notification.Builder(NotificationTestList.this)
-                        .setSmallIcon(R.drawable.icon1)
-                        .setStyle(bigText)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("hihi")
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent2())
-                        .setTopic(new Notification.Topic("hello", "Hello"))
-                        .build();
-
-                mNM.notify(70, n);
-            }
-        },
-
-        new Test("with topic GoodBye") {
-            public void run() {
-                Notification.BigPictureStyle picture = new Notification.BigPictureStyle();
-                picture.bigPicture(BitmapFactory.decodeResource(getResources(),
-                        R.id.large_icon_pineapple2));
-                Notification n = new Notification.Builder(NotificationTestList.this)
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("byebye")
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent2())
-                        .setTopic(new Notification.Topic("bye", "Goodbye"))
-                        .setStyle(picture)
-                        .build();
-
-                mNM.notify(71, n);
-            }
-        },
-        new Test("with topic Bananas") {
-            public void run() {
-                Notification.BigTextStyle bigText = new Notification.BigTextStyle();
-                bigText.bigText("bananas are great\nso tasty\nyum\nyum\nyum\n");
-                Notification n = new Notification.Builder(NotificationTestList.this)
-                        .setSmallIcon(R.drawable.icon1)
-                        .setStyle(bigText)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("bananananana")
-                        .setContentText("This is a banana!!!")
-                        .setContentIntent(makeIntent2())
-                        .setTopic(new Notification.Topic("bananas", "Bananas"))
-                        .build();
-
-                mNM.notify(72, n);
-            }
-        },
-
-            new Test("with delete intent") {
-                public void run() {
-                    Notification.BigTextStyle bigText = new Notification.BigTextStyle();
-                    bigText.bigText("bananas are great\nso tasty\nyum\nyum\nyum\n");
-                    Notification n = new Notification.Builder(NotificationTestList.this)
-                            .setSmallIcon(R.drawable.icon1)
-                            .setStyle(bigText)
-                            .setWhen(mActivityCreateTime)
-                            .setContentTitle("bananananana")
-                            .setContentText("This is a banana!!!")
-                            .setTopic(new Notification.Topic("bananas", "Bananas"))
-                            .setDeleteIntent(makeIntent2())
-                            .build();
-
-                    mNM.notify(73, n);
-                }
-            },
-
             new Test("Is blocked?") {
                 public void run() {
                     Toast.makeText(NotificationTestList.this,
@@ -242,18 +170,10 @@
                 }
             },
 
-            new Test("Topic banana importance?") {
+            new Test("importance?") {
                 public void run() {
                     Toast.makeText(NotificationTestList.this,
-                            "bananas importance? " + mNM.getImportance("bananas"),
-                            Toast.LENGTH_LONG).show();
-                }
-            },
-
-            new Test("Topic garbage importance?") {
-                public void run() {
-                    Toast.makeText(NotificationTestList.this,
-                            "garbage importance? " + mNM.getImportance("garbage"),
+                            "importance? " + mNM.getImportance(),
                             Toast.LENGTH_LONG).show();
                 }
             },
diff --git a/tests/touchlag/Android.mk b/tests/touchlag/Android.mk
index 4f8aa1e..70b1989 100644
--- a/tests/touchlag/Android.mk
+++ b/tests/touchlag/Android.mk
@@ -9,6 +9,8 @@
 
 LOCAL_MODULE:= test-touchlag
 
+LOCAL_CFLAGS += -Wall -Wextra -Werror
+
 LOCAL_MODULE_TAGS := tests
 
 include $(BUILD_EXECUTABLE)
diff --git a/tests/touchlag/touchlag.cpp b/tests/touchlag/touchlag.cpp
index df4befb..9264a25 100644
--- a/tests/touchlag/touchlag.cpp
+++ b/tests/touchlag/touchlag.cpp
@@ -54,11 +54,11 @@
 void drawTwoPixels(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w) {
     if (y>0 && y<ssize_t(buf->h)) {
         uint32_t* bits = buf->pixels + y * buf->s;
-        if (x>=0 && x<buf->w) {
+        if (x>=0 && x<ssize_t(buf->w)) {
             bits[x] = pixel;
         }
         ssize_t W(w);
-        if ((x+W)>=0 && (x+W)<buf->w) {
+        if ((x+W)>=0 && (x+W)<ssize_t(buf->w)) {
             bits[x+W] = pixel;
         }
     }
@@ -251,13 +251,13 @@
     Queue queue;
 
 
-    int x=0, y=0, down=0;
+    int x=0, y=0;
     int lag_x=0, lag_y=0;
 
     clearBuffer(&framebuffer, 0);
     while (true) {
         uint32_t crt = 0;
-        int err = ioctl(fd, FBIO_WAITFORVSYNC, &crt);
+        ioctl(fd, FBIO_WAITFORVSYNC, &crt);
 
         // draw beam marker
         drawRect(&framebuffer, 0x400000, framebuffer.w-2, 0, 2, framebuffer.h);
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 31da670..ed12bdf 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -331,6 +331,7 @@
      */
     public static class InformationElement {
         public static final int EID_SSID = 0;
+        public static final int EID_TIM = 5;
         public static final int EID_BSS_LOAD = 11;
         public static final int EID_RSN = 48;
         public static final int EID_HT_OPERATION = 61;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index cce8386..ddd8f43 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -403,6 +403,15 @@
 
     /**
      * @hide
+     * The number of beacon intervals between Delivery Traffic Indication Maps (DTIM)
+     * This value is populated from scan results that contain Beacon Frames, which are infrequent.
+     * The value is not guaranteed to be set or current (Although it SHOULDNT change once set)
+     * Valid values are from 1 - 255. Initialized here as 0, use this to check if set.
+     */
+    public int dtimInterval = 0;
+
+    /**
+     * @hide
      * Uid of app creating the configuration
      */
     @SystemApi
@@ -1298,6 +1307,7 @@
         lastUpdateUid = -1;
         creatorUid = -1;
         shared = true;
+        dtimInterval = 0;
     }
 
     /**
@@ -2044,4 +2054,4 @@
         config.allowedKeyManagement.set(in.readInt());
         return config;
     }
-}
\ No newline at end of file
+}
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 362738e..58e8761 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -20,6 +20,7 @@
 import android.os.Parcelable;
 import android.security.Credentials;
 import android.text.TextUtils;
+import android.util.Log;
 
 import java.io.ByteArrayInputStream;
 import java.nio.charset.StandardCharsets;
@@ -116,10 +117,30 @@
     public static final String CA_CERT_ALIAS_DELIMITER = " ";
 
 
+    // Fields to copy verbatim from wpa_supplicant.
+    private static final String[] SUPPLICANT_CONFIG_KEYS = new String[] {
+            IDENTITY_KEY,
+            ANON_IDENTITY_KEY,
+            PASSWORD_KEY,
+            CLIENT_CERT_KEY,
+            CA_CERT_KEY,
+            SUBJECT_MATCH_KEY,
+            ENGINE_KEY,
+            ENGINE_ID_KEY,
+            PRIVATE_KEY_ID_KEY,
+            ALTSUBJECT_MATCH_KEY,
+            DOM_SUFFIX_MATCH_KEY,
+            CA_PATH_KEY
+    };
+
     private HashMap<String, String> mFields = new HashMap<String, String>();
     private X509Certificate[] mCaCerts;
     private PrivateKey mClientPrivateKey;
     private X509Certificate mClientCertificate;
+    private int mEapMethod = Eap.NONE;
+    private int mPhase2Method = Phase2.NONE;
+
+    private static final String TAG = "WifiEnterpriseConfig";
 
     public WifiEnterpriseConfig() {
         // Do not set defaults so that the enterprise fields that are not changed
@@ -134,6 +155,8 @@
         for (String key : source.mFields.keySet()) {
             mFields.put(key, source.mFields.get(key));
         }
+        mEapMethod = source.mEapMethod;
+        mPhase2Method = source.mPhase2Method;
     }
 
     @Override
@@ -149,6 +172,8 @@
             dest.writeString(entry.getValue());
         }
 
+        dest.writeInt(mEapMethod);
+        dest.writeInt(mPhase2Method);
         writeCertificates(dest, mCaCerts);
 
         if (mClientPrivateKey != null) {
@@ -200,6 +225,8 @@
                         enterpriseConfig.mFields.put(key, value);
                     }
 
+                    enterpriseConfig.mEapMethod = in.readInt();
+                    enterpriseConfig.mPhase2Method = in.readInt();
                     enterpriseConfig.mCaCerts = readCertificates(in);
 
                     PrivateKey userKey = null;
@@ -296,7 +323,8 @@
         public static final int MSCHAPV2    = 3;
         /** Generic Token Card */
         public static final int GTC         = 4;
-        private static final String PREFIX = "auth=";
+        private static final String AUTH_PREFIX = "auth=";
+        private static final String AUTHEAP_PREFIX = "autheap=";
         /** @hide */
         public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP",
                 "MSCHAPV2", "GTC" };
@@ -305,11 +333,98 @@
         private Phase2() {}
     }
 
-    /** Internal use only
+    // Loader and saver interfaces for exchanging data with wpa_supplicant.
+    // TODO: Decouple this object (which is just a placeholder of the configuration)
+    // from the implementation that knows what wpa_supplicant wants.
+    /**
+     * Interface used for retrieving supplicant configuration from WifiEnterpriseConfig
      * @hide
      */
-    public HashMap<String, String> getFields() {
-        return mFields;
+    public interface SupplicantSaver {
+        /**
+         * Set a value within wpa_supplicant configuration
+         * @param key index to set within wpa_supplciant
+         * @param value the value for the key
+         * @return true if successful; false otherwise
+         */
+        boolean saveValue(String key, String value);
+    }
+
+    /**
+     * Interface used for populating a WifiEnterpriseConfig from supplicant configuration
+     * @hide
+     */
+    public interface SupplicantLoader {
+        /**
+         * Returns a value within wpa_supplicant configuration
+         * @param key index to set within wpa_supplciant
+         * @return string value if successful; null otherwise
+         */
+        String loadValue(String key);
+    }
+
+    /**
+     * Internal use only; supply field values to wpa_supplicant config.  The configuration
+     * process aborts on the first failed call on {@code saver}.
+     * @param saver proxy for setting configuration in wpa_supplciant
+     * @return whether the save succeeded on all attempts
+     * @hide
+     */
+    public boolean saveToSupplicant(SupplicantSaver saver) {
+        if (!isEapMethodValid()) {
+            return false;
+        }
+
+        for (String key : mFields.keySet()) {
+            if (!saver.saveValue(key, mFields.get(key))) {
+                return false;
+            }
+        }
+
+        if (!saver.saveValue(EAP_KEY, Eap.strings[mEapMethod])) {
+            return false;
+        }
+
+        if (mEapMethod != Eap.TLS && mPhase2Method != Phase2.NONE) {
+            boolean is_autheap = mEapMethod == Eap.TTLS && mPhase2Method == Phase2.GTC;
+            String prefix = is_autheap ? Phase2.AUTHEAP_PREFIX : Phase2.AUTH_PREFIX;
+            String value = convertToQuotedString(prefix + Phase2.strings[mPhase2Method]);
+            return saver.saveValue(PHASE2_KEY, value);
+        } else if (mPhase2Method == Phase2.NONE) {
+            // By default, send a null phase 2 to clear old configuration values.
+            return saver.saveValue(PHASE2_KEY, null);
+        } else {
+            Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies a "
+                    + "phase 2 method but the phase1 method does not support it.");
+            return false;
+        }
+    }
+
+    /**
+     * Internal use only; retrieve configuration from wpa_supplicant config.
+     * @param loader proxy for retrieving configuration keys from wpa_supplicant
+     * @hide
+     */
+    public void loadFromSupplicant(SupplicantLoader loader) {
+        for (String key : SUPPLICANT_CONFIG_KEYS) {
+            String value = loader.loadValue(key);
+            if (value == null) {
+                mFields.put(key, EMPTY_VALUE);
+            } else {
+                mFields.put(key, value);
+            }
+        }
+        String eapMethod  = loader.loadValue(EAP_KEY);
+        mEapMethod = getStringIndex(Eap.strings, eapMethod, Eap.NONE);
+
+        String phase2Method = removeDoubleQuotes(loader.loadValue(PHASE2_KEY));
+        // Remove "auth=" or "autheap=" prefix.
+        if (phase2Method.startsWith(Phase2.AUTH_PREFIX)) {
+            phase2Method = phase2Method.substring(Phase2.AUTH_PREFIX.length());
+        } else if (phase2Method.startsWith(Phase2.AUTHEAP_PREFIX)) {
+            phase2Method = phase2Method.substring(Phase2.AUTHEAP_PREFIX.length());
+        }
+        mPhase2Method = getStringIndex(Phase2.strings, phase2Method, Phase2.NONE);
     }
 
     /**
@@ -330,7 +445,7 @@
             case Eap.SIM:
             case Eap.AKA:
             case Eap.AKA_PRIME:
-                mFields.put(EAP_KEY, Eap.strings[eapMethod]);
+                mEapMethod = eapMethod;
                 mFields.put(OPP_KEY_CACHING, "1");
                 break;
             default:
@@ -343,8 +458,7 @@
      * @return eap method configured
      */
     public int getEapMethod() {
-        String eapMethod  = mFields.get(EAP_KEY);
-        return getStringIndex(Eap.strings, eapMethod, Eap.NONE);
+        return mEapMethod;
     }
 
     /**
@@ -359,15 +473,11 @@
     public void setPhase2Method(int phase2Method) {
         switch (phase2Method) {
             case Phase2.NONE:
-                mFields.put(PHASE2_KEY, EMPTY_VALUE);
-                break;
-            /** Valid methods */
             case Phase2.PAP:
             case Phase2.MSCHAP:
             case Phase2.MSCHAPV2:
             case Phase2.GTC:
-                mFields.put(PHASE2_KEY, convertToQuotedString(
-                        Phase2.PREFIX + Phase2.strings[phase2Method]));
+                mPhase2Method = phase2Method;
                 break;
             default:
                 throw new IllegalArgumentException("Unknown Phase 2 method");
@@ -379,12 +489,7 @@
      * @return a phase 2 method defined at {@link Phase2}
      * */
     public int getPhase2Method() {
-        String phase2Method = removeDoubleQuotes(mFields.get(PHASE2_KEY));
-        // Remove auth= prefix
-        if (phase2Method.startsWith(Phase2.PREFIX)) {
-            phase2Method = phase2Method.substring(Phase2.PREFIX.length());
-        }
-        return getStringIndex(Phase2.strings, phase2Method, Phase2.NONE);
+        return mPhase2Method;
     }
 
     /**
@@ -412,7 +517,8 @@
         setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity, "");
     }
 
-    /** Get the anonymous identity
+    /**
+     * Get the anonymous identity
      * @return anonymous identity
      */
     public String getAnonymousIdentity() {
@@ -839,18 +945,15 @@
     }
 
     /** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */
-    String getKeyId(WifiEnterpriseConfig current) {
-        String eap = mFields.get(EAP_KEY);
-        String phase2 = mFields.get(PHASE2_KEY);
-
-        // If either eap or phase2 are not initialized, use current config details
-        if (TextUtils.isEmpty((eap))) {
-            eap = current.mFields.get(EAP_KEY);
+    public String getKeyId(WifiEnterpriseConfig current) {
+        // If EAP method is not initialized, use current config details
+        if (mEapMethod == Eap.NONE) {
+            return (current != null) ? current.getKeyId(null) : EMPTY_VALUE;
         }
-        if (TextUtils.isEmpty(phase2)) {
-            phase2 = current.mFields.get(PHASE2_KEY);
+        if (!isEapMethodValid()) {
+            return EMPTY_VALUE;
         }
-        return eap + "_" + phase2;
+        return Eap.strings[mEapMethod] + "_" + Phase2.strings[mPhase2Method];
     }
 
     private String removeDoubleQuotes(String string) {
@@ -867,7 +970,8 @@
         return "\"" + string + "\"";
     }
 
-    /** Returns the index at which the toBeFound string is found in the array.
+    /**
+     * Returns the index at which the toBeFound string is found in the array.
      * @param arr array of strings
      * @param toBeFound string to be found
      * @param defaultIndex default index to be returned when string is not found
@@ -881,13 +985,16 @@
         return defaultIndex;
     }
 
-    /** Returns the field value for the key.
+    /**
+     * Returns the field value for the key.
      * @param key into the hash
      * @param prefix is the prefix that the value may have
      * @return value
      * @hide
      */
     public String getFieldValue(String key, String prefix) {
+        // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
+        // neither of these keys should be retrieved in this manner.
         String value = mFields.get(key);
         // Uninitialized or known to be empty after reading from supplicant
         if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
@@ -900,13 +1007,16 @@
         }
     }
 
-    /** Set a value with an optional prefix at key
+    /**
+     * Set a value with an optional prefix at key
      * @param key into the hash
      * @param value to be set
      * @param prefix an optional value to be prefixed to actual value
      * @hide
      */
     public void setFieldValue(String key, String value, String prefix) {
+        // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
+        // neither of these keys should be set in this manner.
         if (TextUtils.isEmpty(value)) {
             mFields.put(key, EMPTY_VALUE);
         } else {
@@ -915,13 +1025,16 @@
     }
 
 
-    /** Set a value with an optional prefix at key
+    /**
+     * Set a value with an optional prefix at key
      * @param key into the hash
      * @param value to be set
      * @param prefix an optional value to be prefixed to actual value
      * @hide
      */
     public void setFieldValue(String key, String value) {
+        // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
+        // neither of these keys should be set in this manner.
         if (TextUtils.isEmpty(value)) {
            mFields.put(key, EMPTY_VALUE);
         } else {
@@ -939,4 +1052,25 @@
         }
         return sb.toString();
     }
+
+    /**
+     * Returns whether the EAP method data is valid, i.e., whether mEapMethod and mPhase2Method
+     * are valid indices into {@code Eap.strings[]} and {@code Phase2.strings[]} respectively.
+     */
+    private boolean isEapMethodValid() {
+        if (mEapMethod == Eap.NONE) {
+            Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies no EAP method.");
+            return false;
+        }
+        if (mEapMethod < 0 || mEapMethod >= Eap.strings.length) {
+            Log.e(TAG, "mEapMethod is invald for WiFi enterprise configuration: " + mEapMethod);
+            return false;
+        }
+        if (mPhase2Method < 0 || mPhase2Method >= Phase2.strings.length) {
+            Log.e(TAG, "mPhase2Method is invald for WiFi enterprise configuration: "
+                    + mPhase2Method);
+            return false;
+        }
+        return true;
+    }
 }