Merge "Binder: Don't attempt to catch OutOfMemoryError"
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
index f114ef4..6e802a9 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
@@ -95,7 +95,7 @@
     }
 
     @Test
-    public void createAndStartUserPerf() throws Exception {
+    public void createAndStartUser() throws Exception {
         while (mRunner.keepRunning()) {
             final UserInfo userInfo = mUm.createUser("TestUser", 0);
 
@@ -111,7 +111,7 @@
     }
 
     @Test
-    public void switchUserPerf() throws Exception {
+    public void switchUser() throws Exception {
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final int startUser = mAm.getCurrentUser();
@@ -128,7 +128,7 @@
     }
 
     @Test
-    public void stopUserPerf() throws Exception {
+    public void stopUser() throws Exception {
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final UserInfo userInfo = mUm.createUser("TestUser", 0);
@@ -147,7 +147,7 @@
     }
 
     @Test
-    public void lockedBootCompletedPerf() throws Exception {
+    public void lockedBootCompleted() throws Exception {
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final int startUser = mAm.getCurrentUser();
@@ -167,7 +167,7 @@
     }
 
     @Test
-    public void managedProfileUnlockPerf() throws Exception {
+    public void managedProfileUnlock() throws Exception {
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final UserInfo userInfo = mUm.createProfileForUser("TestUser",
@@ -186,7 +186,7 @@
     }
 
     @Test
-    public void ephemeralUserStoppedPerf() throws Exception {
+    public void ephemeralUserStopped() throws Exception {
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final int startUser = mAm.getCurrentUser();
@@ -218,7 +218,7 @@
     }
 
     @Test
-    public void managedProfileStoppedPerf() throws Exception {
+    public void managedProfileStopped() throws Exception {
         while (mRunner.keepRunning()) {
             mRunner.pauseTiming();
             final UserInfo userInfo = mUm.createProfileForUser("TestUser",
diff --git a/api/current.txt b/api/current.txt
index 38bb68b..293a765 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -388,6 +388,7 @@
     field public static final int childIndicatorRight = 16843024; // 0x1010110
     field public static final int childIndicatorStart = 16843731; // 0x10103d3
     field public static final int choiceMode = 16843051; // 0x101012b
+    field public static final int classLoader = 16844139; // 0x101056b
     field public static final int clearTaskOnLaunch = 16842773; // 0x1010015
     field public static final int clickable = 16842981; // 0x10100e5
     field public static final int clipChildren = 16842986; // 0x10100ea
@@ -6106,17 +6107,15 @@
 
   public final class WallpaperColors implements android.os.Parcelable {
     ctor public WallpaperColors(android.os.Parcel);
-    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color, int);
+    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color);
     method public int describeContents();
     method public static android.app.WallpaperColors fromBitmap(android.graphics.Bitmap);
     method public static android.app.WallpaperColors fromDrawable(android.graphics.drawable.Drawable);
-    method public int getColorHints();
     method public android.graphics.Color getPrimaryColor();
     method public android.graphics.Color getSecondaryColor();
     method public android.graphics.Color getTertiaryColor();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
-    field public static final int HINT_SUPPORTS_DARK_TEXT = 1; // 0x1
   }
 
   public final class WallpaperInfo implements android.os.Parcelable {
@@ -36958,7 +36957,7 @@
   }
 
   public static class CharSequenceTransformation.Builder {
-    ctor public CharSequenceTransformation.Builder();
+    ctor public CharSequenceTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, java.lang.String);
     method public android.service.autofill.CharSequenceTransformation.Builder addField(android.view.autofill.AutofillId, java.lang.String, java.lang.String);
     method public android.service.autofill.CharSequenceTransformation build();
   }
@@ -37055,7 +37054,7 @@
   }
 
   public static class ImageTransformation.Builder {
-    ctor public ImageTransformation.Builder(android.view.autofill.AutofillId);
+    ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int);
     method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int);
     method public android.service.autofill.ImageTransformation build();
   }
@@ -38340,6 +38339,7 @@
     field public static final int FD_CLOEXEC;
     field public static final int FIONREAD;
     field public static final int F_DUPFD;
+    field public static final int F_DUPFD_CLOEXEC;
     field public static final int F_GETFD;
     field public static final int F_GETFL;
     field public static final int F_GETLK;
@@ -38434,7 +38434,9 @@
     field public static final int NI_NUMERICSERV;
     field public static final int O_ACCMODE;
     field public static final int O_APPEND;
+    field public static final int O_CLOEXEC;
     field public static final int O_CREAT;
+    field public static final int O_DSYNC;
     field public static final int O_EXCL;
     field public static final int O_NOCTTY;
     field public static final int O_NOFOLLOW;
@@ -48589,6 +48591,10 @@
     method public abstract int rendererPriorityAtExit();
   }
 
+  public abstract class SafeBrowsingResponse {
+    ctor public SafeBrowsingResponse();
+  }
+
   public class ServiceWorkerClient {
     ctor public ServiceWorkerClient();
     method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest);
@@ -49126,7 +49132,7 @@
     method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String);
     method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError);
     method public boolean onRenderProcessGone(android.webkit.WebView, android.webkit.RenderProcessGoneDetail);
-    method public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.ValueCallback<java.lang.Integer>);
+    method public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
     method public void onScaleChanged(android.webkit.WebView, float, float);
     method public deprecated void onTooManyRedirects(android.webkit.WebView, android.os.Message, android.os.Message);
     method public void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent);
@@ -49151,9 +49157,6 @@
     field public static final int ERROR_UNSAFE_RESOURCE = -16; // 0xfffffff0
     field public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3; // 0xfffffffd
     field public static final int ERROR_UNSUPPORTED_SCHEME = -10; // 0xfffffff6
-    field public static final int SAFE_BROWSING_ACTION_BACK_TO_SAFETY = 2; // 0x2
-    field public static final int SAFE_BROWSING_ACTION_PROCEED = 1; // 0x1
-    field public static final int SAFE_BROWSING_ACTION_SHOW_INTERSTITIAL = 0; // 0x0
     field public static final int SAFE_BROWSING_THREAT_MALWARE = 1; // 0x1
     field public static final int SAFE_BROWSING_THREAT_PHISHING = 2; // 0x2
     field public static final int SAFE_BROWSING_THREAT_UNKNOWN = 0; // 0x0
@@ -52248,6 +52251,7 @@
   }
 
   public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public InMemoryDexClassLoader(java.nio.ByteBuffer[], java.lang.ClassLoader);
     ctor public InMemoryDexClassLoader(java.nio.ByteBuffer, java.lang.ClassLoader);
   }
 
diff --git a/api/removed.txt b/api/removed.txt
index 49b72e15..3968fd3 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -15,6 +15,7 @@
 
   public class Notification implements android.os.Parcelable {
     method public deprecated java.lang.String getChannel();
+    method public static java.lang.Class<? extends android.app.Notification.Style> getNotificationStyleClass(java.lang.String);
     method public deprecated long getTimeout();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
@@ -451,6 +452,26 @@
 
 }
 
+package android.service.notification {
+
+  public abstract class NotificationListenerService extends android.app.Service {
+    method public android.service.notification.StatusBarNotification[] getActiveNotifications(int);
+    method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[], int);
+    method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException;
+    method public final void setOnNotificationPostedTrim(int);
+    method public final void snoozeNotification(java.lang.String, java.lang.String);
+    method public void unregisterAsSystemService() throws android.os.RemoteException;
+    field public static final int TRIM_FULL = 0; // 0x0
+    field public static final int TRIM_LIGHT = 1; // 0x1
+  }
+
+  public static class NotificationListenerService.Ranking {
+    method public java.util.List<java.lang.String> getAdditionalPeople();
+    method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
+  }
+
+}
+
 package android.speech.tts {
 
   public abstract class UtteranceProgressListener {
diff --git a/api/system-current.txt b/api/system-current.txt
index d98319c..e6675f6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -511,6 +511,7 @@
     field public static final int childIndicatorRight = 16843024; // 0x1010110
     field public static final int childIndicatorStart = 16843731; // 0x10103d3
     field public static final int choiceMode = 16843051; // 0x101012b
+    field public static final int classLoader = 16844139; // 0x101056b
     field public static final int clearTaskOnLaunch = 16842773; // 0x1010015
     field public static final int clickable = 16842981; // 0x10100e5
     field public static final int clipChildren = 16842986; // 0x10100ea
@@ -6318,17 +6319,15 @@
 
   public final class WallpaperColors implements android.os.Parcelable {
     ctor public WallpaperColors(android.os.Parcel);
-    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color, int);
+    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color);
     method public int describeContents();
     method public static android.app.WallpaperColors fromBitmap(android.graphics.Bitmap);
     method public static android.app.WallpaperColors fromDrawable(android.graphics.drawable.Drawable);
-    method public int getColorHints();
     method public android.graphics.Color getPrimaryColor();
     method public android.graphics.Color getSecondaryColor();
     method public android.graphics.Color getTertiaryColor();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
-    field public static final int HINT_SUPPORTS_DARK_TEXT = 1; // 0x1
   }
 
   public final class WallpaperInfo implements android.os.Parcelable {
@@ -40039,7 +40038,7 @@
   }
 
   public static class CharSequenceTransformation.Builder {
-    ctor public CharSequenceTransformation.Builder();
+    ctor public CharSequenceTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, java.lang.String);
     method public android.service.autofill.CharSequenceTransformation.Builder addField(android.view.autofill.AutofillId, java.lang.String, java.lang.String);
     method public android.service.autofill.CharSequenceTransformation build();
   }
@@ -40136,7 +40135,7 @@
   }
 
   public static class ImageTransformation.Builder {
-    ctor public ImageTransformation.Builder(android.view.autofill.AutofillId);
+    ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int);
     method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int);
     method public android.service.autofill.ImageTransformation build();
   }
@@ -41564,6 +41563,7 @@
     field public static final int FD_CLOEXEC;
     field public static final int FIONREAD;
     field public static final int F_DUPFD;
+    field public static final int F_DUPFD_CLOEXEC;
     field public static final int F_GETFD;
     field public static final int F_GETFL;
     field public static final int F_GETLK;
@@ -41658,7 +41658,9 @@
     field public static final int NI_NUMERICSERV;
     field public static final int O_ACCMODE;
     field public static final int O_APPEND;
+    field public static final int O_CLOEXEC;
     field public static final int O_CREAT;
+    field public static final int O_DSYNC;
     field public static final int O_EXCL;
     field public static final int O_NOCTTY;
     field public static final int O_NOFOLLOW;
@@ -52200,6 +52202,10 @@
     method public abstract int rendererPriorityAtExit();
   }
 
+  public abstract class SafeBrowsingResponse {
+    ctor public SafeBrowsingResponse();
+  }
+
   public class ServiceWorkerClient {
     ctor public ServiceWorkerClient();
     method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest);
@@ -52808,7 +52814,7 @@
     method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String);
     method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError);
     method public boolean onRenderProcessGone(android.webkit.WebView, android.webkit.RenderProcessGoneDetail);
-    method public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.ValueCallback<java.lang.Integer>);
+    method public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
     method public void onScaleChanged(android.webkit.WebView, float, float);
     method public deprecated void onTooManyRedirects(android.webkit.WebView, android.os.Message, android.os.Message);
     method public void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent);
@@ -52833,9 +52839,6 @@
     field public static final int ERROR_UNSAFE_RESOURCE = -16; // 0xfffffff0
     field public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3; // 0xfffffffd
     field public static final int ERROR_UNSUPPORTED_SCHEME = -10; // 0xfffffff6
-    field public static final int SAFE_BROWSING_ACTION_BACK_TO_SAFETY = 2; // 0x2
-    field public static final int SAFE_BROWSING_ACTION_PROCEED = 1; // 0x1
-    field public static final int SAFE_BROWSING_ACTION_SHOW_INTERSTITIAL = 0; // 0x0
     field public static final int SAFE_BROWSING_THREAT_MALWARE = 1; // 0x1
     field public static final int SAFE_BROWSING_THREAT_PHISHING = 2; // 0x2
     field public static final int SAFE_BROWSING_THREAT_UNKNOWN = 0; // 0x0
@@ -56173,6 +56176,7 @@
   }
 
   public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public InMemoryDexClassLoader(java.nio.ByteBuffer[], java.lang.ClassLoader);
     ctor public InMemoryDexClassLoader(java.nio.ByteBuffer, java.lang.ClassLoader);
   }
 
diff --git a/api/test-current.txt b/api/test-current.txt
index 94bfe84..6d16e35 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -388,6 +388,7 @@
     field public static final int childIndicatorRight = 16843024; // 0x1010110
     field public static final int childIndicatorStart = 16843731; // 0x10103d3
     field public static final int choiceMode = 16843051; // 0x101012b
+    field public static final int classLoader = 16844139; // 0x101056b
     field public static final int clearTaskOnLaunch = 16842773; // 0x1010015
     field public static final int clickable = 16842981; // 0x10100e5
     field public static final int clipChildren = 16842986; // 0x10100ea
@@ -6127,17 +6128,15 @@
 
   public final class WallpaperColors implements android.os.Parcelable {
     ctor public WallpaperColors(android.os.Parcel);
-    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color, int);
+    ctor public WallpaperColors(android.graphics.Color, android.graphics.Color, android.graphics.Color);
     method public int describeContents();
     method public static android.app.WallpaperColors fromBitmap(android.graphics.Bitmap);
     method public static android.app.WallpaperColors fromDrawable(android.graphics.drawable.Drawable);
-    method public int getColorHints();
     method public android.graphics.Color getPrimaryColor();
     method public android.graphics.Color getSecondaryColor();
     method public android.graphics.Color getTertiaryColor();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
-    field public static final int HINT_SUPPORTS_DARK_TEXT = 1; // 0x1
   }
 
   public final class WallpaperInfo implements android.os.Parcelable {
@@ -37125,13 +37124,14 @@
   }
 
   public final class CharSequenceTransformation implements android.os.Parcelable {
+    method public void apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.CharSequenceTransformation> CREATOR;
   }
 
   public static class CharSequenceTransformation.Builder {
-    ctor public CharSequenceTransformation.Builder();
+    ctor public CharSequenceTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, java.lang.String);
     method public android.service.autofill.CharSequenceTransformation.Builder addField(android.view.autofill.AutofillId, java.lang.String, java.lang.String);
     method public android.service.autofill.CharSequenceTransformation build();
   }
@@ -37222,13 +37222,14 @@
   }
 
   public final class ImageTransformation implements android.os.Parcelable {
+    method public void apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.ImageTransformation> CREATOR;
   }
 
   public static class ImageTransformation.Builder {
-    ctor public ImageTransformation.Builder(android.view.autofill.AutofillId);
+    ctor public ImageTransformation.Builder(android.view.autofill.AutofillId, java.lang.String, int);
     method public android.service.autofill.ImageTransformation.Builder addOption(java.lang.String, int);
     method public android.service.autofill.ImageTransformation build();
   }
@@ -37236,6 +37237,7 @@
   public final class LuhnChecksumValidator implements android.os.Parcelable {
     ctor public LuhnChecksumValidator(android.view.autofill.AutofillId...);
     method public int describeContents();
+    method public boolean isValid(android.service.autofill.ValueFinder);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.LuhnChecksumValidator> CREATOR;
   }
@@ -37297,6 +37299,10 @@
     method public static android.service.autofill.Validator or(android.service.autofill.Validator...);
   }
 
+  public abstract interface ValueFinder {
+    method public abstract java.lang.String findByAutofillId(android.view.autofill.AutofillId);
+  }
+
 }
 
 package android.service.carrier {
@@ -37604,7 +37610,6 @@
     method public static void requestRebind(android.content.ComponentName);
     method public final void requestUnbind();
     method public final void setNotificationsShown(java.lang.String[]);
-    method public final void snoozeNotification(java.lang.String, java.lang.String);
     method public final void snoozeNotification(java.lang.String, long);
     method public final void updateNotificationChannel(java.lang.String, android.os.UserHandle, android.app.NotificationChannel);
     field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
@@ -37645,14 +37650,12 @@
   public static class NotificationListenerService.Ranking {
     ctor public NotificationListenerService.Ranking();
     method public boolean canShowBadge();
-    method public java.util.List<java.lang.String> getAdditionalPeople();
     method public android.app.NotificationChannel getChannel();
     method public int getImportance();
     method public java.lang.CharSequence getImportanceExplanation();
     method public java.lang.String getKey();
     method public java.lang.String getOverrideGroupKey();
     method public int getRank();
-    method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
     method public int getSuppressedVisualEffects();
     method public boolean isAmbient();
     method public boolean matchesInterruptionFilter();
@@ -38554,6 +38557,7 @@
     field public static final int FD_CLOEXEC;
     field public static final int FIONREAD;
     field public static final int F_DUPFD;
+    field public static final int F_DUPFD_CLOEXEC;
     field public static final int F_GETFD;
     field public static final int F_GETFL;
     field public static final int F_GETLK;
@@ -38648,7 +38652,9 @@
     field public static final int NI_NUMERICSERV;
     field public static final int O_ACCMODE;
     field public static final int O_APPEND;
+    field public static final int O_CLOEXEC;
     field public static final int O_CREAT;
+    field public static final int O_DSYNC;
     field public static final int O_EXCL;
     field public static final int O_NOCTTY;
     field public static final int O_NOFOLLOW;
@@ -44233,6 +44239,7 @@
     method public abstract void invalidate();
     method public void invalidateContentRect();
     method public boolean isTitleOptional();
+    method public boolean isUiFocusable();
     method public void onWindowFocusChanged(boolean);
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
@@ -48263,6 +48270,7 @@
 package android.view.autofill {
 
   public final class AutofillId implements android.os.Parcelable {
+    ctor public AutofillId(int);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.autofill.AutofillId> CREATOR;
@@ -49012,6 +49020,10 @@
     method public abstract int rendererPriorityAtExit();
   }
 
+  public abstract class SafeBrowsingResponse {
+    ctor public SafeBrowsingResponse();
+  }
+
   public class ServiceWorkerClient {
     ctor public ServiceWorkerClient();
     method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest);
@@ -49549,7 +49561,7 @@
     method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String);
     method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError);
     method public boolean onRenderProcessGone(android.webkit.WebView, android.webkit.RenderProcessGoneDetail);
-    method public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.ValueCallback<java.lang.Integer>);
+    method public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
     method public void onScaleChanged(android.webkit.WebView, float, float);
     method public deprecated void onTooManyRedirects(android.webkit.WebView, android.os.Message, android.os.Message);
     method public void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent);
@@ -49574,9 +49586,6 @@
     field public static final int ERROR_UNSAFE_RESOURCE = -16; // 0xfffffff0
     field public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3; // 0xfffffffd
     field public static final int ERROR_UNSUPPORTED_SCHEME = -10; // 0xfffffff6
-    field public static final int SAFE_BROWSING_ACTION_BACK_TO_SAFETY = 2; // 0x2
-    field public static final int SAFE_BROWSING_ACTION_PROCEED = 1; // 0x1
-    field public static final int SAFE_BROWSING_ACTION_SHOW_INTERSTITIAL = 0; // 0x0
     field public static final int SAFE_BROWSING_THREAT_MALWARE = 1; // 0x1
     field public static final int SAFE_BROWSING_THREAT_PHISHING = 2; // 0x2
     field public static final int SAFE_BROWSING_THREAT_UNKNOWN = 0; // 0x0
@@ -52686,6 +52695,7 @@
   }
 
   public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public InMemoryDexClassLoader(java.nio.ByteBuffer[], java.lang.ClassLoader);
     ctor public InMemoryDexClassLoader(java.nio.ByteBuffer, java.lang.ClassLoader);
   }
 
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 49b72e15..3968fd3 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -15,6 +15,7 @@
 
   public class Notification implements android.os.Parcelable {
     method public deprecated java.lang.String getChannel();
+    method public static java.lang.Class<? extends android.app.Notification.Style> getNotificationStyleClass(java.lang.String);
     method public deprecated long getTimeout();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
@@ -451,6 +452,26 @@
 
 }
 
+package android.service.notification {
+
+  public abstract class NotificationListenerService extends android.app.Service {
+    method public android.service.notification.StatusBarNotification[] getActiveNotifications(int);
+    method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[], int);
+    method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException;
+    method public final void setOnNotificationPostedTrim(int);
+    method public final void snoozeNotification(java.lang.String, java.lang.String);
+    method public void unregisterAsSystemService() throws android.os.RemoteException;
+    field public static final int TRIM_FULL = 0; // 0x0
+    field public static final int TRIM_LIGHT = 1; // 0x1
+  }
+
+  public static class NotificationListenerService.Ranking {
+    method public java.util.List<java.lang.String> getAdditionalPeople();
+    method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
+  }
+
+}
+
 package android.speech.tts {
 
   public abstract class UtteranceProgressListener {
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index e56417b..1671337 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -235,6 +235,9 @@
     for (i = 0; i < argc; i++) {
         if (known_command == true) {
           runtime.addOption(strdup(argv[i]));
+          // The static analyzer gets upset that we don't ever free the above
+          // string. Since the allocation is from main, leaking it doesn't seem
+          // problematic. NOLINTNEXTLINE
           ALOGV("app_process main add known option '%s'", argv[i]);
           known_command = false;
           continue;
@@ -258,6 +261,9 @@
         }
 
         runtime.addOption(strdup(argv[i]));
+        // The static analyzer gets upset that we don't ever free the above
+        // string. Since the allocation is from main, leaking it doesn't seem
+        // problematic. NOLINTNEXTLINE
         ALOGV("app_process main add option '%s'", argv[i]);
     }
 
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index ad989de..f0189c2 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -414,7 +414,7 @@
                 try {
                     ApkLite baseApk = PackageParser.parseApkLite(file, 0);
                     PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
-                            null, null);
+                            null, null, null);
                     params.sessionParams.setSize(
                             PackageHelper.calculateInstalledSize(pkgLite, false,
                             params.sessionParams.abiOverride));
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 20a4ba1..d432544 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -172,6 +172,9 @@
         @Override
         public void onUidIdle(int uid, boolean disabled) {
         }
+
+        @Override public void onUidCachedChanged(int uid, boolean cached) {
+        }
     }
 
     final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();
@@ -563,6 +566,9 @@
     /** @hide Flag for registerUidObserver: report uid has become active. */
     public static final int UID_OBSERVER_ACTIVE = 1<<3;
 
+    /** @hide Flag for registerUidObserver: report uid cached state has changed. */
+    public static final int UID_OBSERVER_CACHED = 1<<4;
+
     /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: normal free-to-run operation. */
     public static final int APP_START_MODE_NORMAL = 0;
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cb648d5..c994e13 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -658,6 +658,7 @@
     }
 
     static final class DumpHeapData {
+        public boolean runGc;
         String path;
         ParcelFileDescriptor fd;
     }
@@ -1023,8 +1024,10 @@
             sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
         }
 
-        public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
+        @Override
+        public void dumpHeap(boolean managed, boolean runGc, String path, ParcelFileDescriptor fd) {
             DumpHeapData dhd = new DumpHeapData();
+            dhd.runGc = runGc;
             dhd.path = path;
             dhd.fd = fd;
             sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
@@ -5171,6 +5174,11 @@
     }
 
     static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
+        if (dhd.runGc) {
+            System.gc();
+            System.runFinalization();
+            System.gc();
+        }
         if (managed) {
             try {
                 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
@@ -5692,11 +5700,12 @@
         // Allow disk access during application and provider setup. This could
         // block processing ordered broadcasts, but later processing would
         // probably end up doing the same disk access.
+        Application app;
         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
         try {
             // If the app is being launched for full backup or restore, bring it up in
             // a restricted environment with the base application class.
-            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
+            app = data.info.makeApplication(data.restrictedBackupMode, null);
             mInitialApplication = app;
 
             // don't bring up providers in restricted mode; they may depend on the
@@ -5720,20 +5729,20 @@
                     "Exception thrown in onCreate() of "
                     + data.instrumentationName + ": " + e.toString(), e);
             }
-
-            try {
-                mInstrumentation.callApplicationOnCreate(app);
-            } catch (Exception e) {
-                if (!mInstrumentation.onException(app, e)) {
-                    throw new RuntimeException(
-                        "Unable to create application " + app.getClass().getName()
-                        + ": " + e.toString(), e);
-                }
-            }
         } finally {
             StrictMode.setThreadPolicy(savedPolicy);
         }
 
+        try {
+            mInstrumentation.callApplicationOnCreate(app);
+        } catch (Exception e) {
+            if (!mInstrumentation.onException(app, e)) {
+                throw new RuntimeException(
+                    "Unable to create application " + app.getClass().getName()
+                    + ": " + e.toString(), e);
+            }
+        }
+
         // Preload fonts resources
         FontsContract.setApplicationContextForResources(appContext);
         try {
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 2062930..b7c1f4e 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -18,9 +18,8 @@
 
 import android.os.Build;
 import android.os.Trace;
-import android.text.TextUtils;
 import android.util.ArrayMap;
-import com.android.internal.os.PathClassLoaderFactory;
+import com.android.internal.os.ClassLoaderFactory;
 import dalvik.system.PathClassLoader;
 
 /** @hide */
@@ -31,15 +30,16 @@
 
     ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
                                String librarySearchPath, String libraryPermittedPath,
-                               ClassLoader parent) {
+                               ClassLoader parent, String classLoaderName) {
         // For normal usage the cache key used is the same as the zip path.
         return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath,
-                              libraryPermittedPath, parent, zip);
+                              libraryPermittedPath, parent, zip, classLoaderName);
     }
 
     private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
                                        String librarySearchPath, String libraryPermittedPath,
-                                       ClassLoader parent, String cacheKey) {
+                                       ClassLoader parent, String cacheKey,
+                                       String classLoaderName) {
         /*
          * This is the parent we use if they pass "null" in.  In theory
          * this should be the "system" class loader; in practice we
@@ -66,28 +66,25 @@
 
                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
 
-                PathClassLoader pathClassloader = PathClassLoaderFactory.createClassLoader(
-                                                      zip,
-                                                      librarySearchPath,
-                                                      libraryPermittedPath,
-                                                      parent,
-                                                      targetSdkVersion,
-                                                      isBundled);
+                ClassLoader classloader = ClassLoaderFactory.createClassLoader(
+                        zip,  librarySearchPath, libraryPermittedPath, parent,
+                        targetSdkVersion, isBundled, classLoaderName);
 
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupVulkanLayerPath");
-                setupVulkanLayerPath(pathClassloader, librarySearchPath);
+                setupVulkanLayerPath(classloader, librarySearchPath);
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
-                mLoaders.put(cacheKey, pathClassloader);
-                return pathClassloader;
+                mLoaders.put(cacheKey, classloader);
+                return classloader;
             }
 
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
-            PathClassLoader pathClassloader = new PathClassLoader(zip, parent);
+            ClassLoader loader = ClassLoaderFactory.createClassLoader(
+                    zip, null, parent, classLoaderName);
             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-            return pathClassloader;
+            return loader;
         }
     }
 
@@ -105,7 +102,7 @@
         // The cache key is passed separately to enable the stub WebView to be cached under the
         // stub's APK path, when the actual package path is the donor APK.
         return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null,
-                              cacheKey);
+                              cacheKey, null /* classLoaderName */);
     }
 
     private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath);
@@ -122,7 +119,7 @@
         baseDexClassLoader.addDexPath(dexPath);
     }
 
-    private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>();
+    private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<>();
 
     private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders();
 }
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 609ce00..7b6b4b4 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -3101,6 +3101,9 @@
     }
 
     public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        if (mCurState < Fragment.CREATED) {
+            return false;
+        }
         boolean show = false;
         ArrayList<Fragment> newMenus = null;
         for (int i = 0; i < mAdded.size(); i++) {
@@ -3131,6 +3134,9 @@
     }
     
     public boolean dispatchPrepareOptionsMenu(Menu menu) {
+        if (mCurState < Fragment.CREATED) {
+            return false;
+        }
         boolean show = false;
         for (int i = 0; i < mAdded.size(); i++) {
             Fragment f = mAdded.get(i);
@@ -3144,6 +3150,9 @@
     }
     
     public boolean dispatchOptionsItemSelected(MenuItem item) {
+        if (mCurState < Fragment.CREATED) {
+            return false;
+        }
         for (int i = 0; i < mAdded.size(); i++) {
             Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3156,6 +3165,9 @@
     }
     
     public boolean dispatchContextItemSelected(MenuItem item) {
+        if (mCurState < Fragment.CREATED) {
+            return false;
+        }
         for (int i = 0; i < mAdded.size(); i++) {
             Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3168,6 +3180,9 @@
     }
     
     public void dispatchOptionsMenuClosed(Menu menu) {
+        if (mCurState < Fragment.CREATED) {
+            return;
+        }
         for (int i = 0; i < mAdded.size(); i++) {
             Fragment f = mAdded.get(i);
             if (f != null) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index b27e224..3be6f97 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -277,7 +277,7 @@
     int checkGrantUriPermission(int callingUid, in String targetPkg, in Uri uri,
             int modeFlags, int userId);
     // Cause the specified process to dump the specified heap.
-    boolean dumpHeap(in String process, int userId, boolean managed, in String path,
+    boolean dumpHeap(in String process, int userId, boolean managed, boolean runGc, in String path,
             in ParcelFileDescriptor fd);
     int startActivities(in IApplicationThread caller, in String callingPackage,
             in Intent[] intents, in String[] resolvedTypes, in IBinder resultTo,
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index bd8c5c9..7191fc4 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -117,7 +117,7 @@
     void scheduleSuicide();
     void dispatchPackageBroadcast(int cmd, in String[] packages);
     void scheduleCrash(in String msg);
-    void dumpHeap(boolean managed, in String path, in ParcelFileDescriptor fd);
+    void dumpHeap(boolean managed, boolean runGc, in String path, in ParcelFileDescriptor fd);
     void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix,
             in String[] args);
     void clearDnsCache();
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index ae64875..01a9cbf 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -43,4 +43,14 @@
      * a sufficient period of time, or all of its processes have gone away.
      */
     void onUidIdle(int uid, boolean disabled);
+
+    /**
+     * Report when the cached state of a uid has changed.
+     * If true, a uid has become cached -- that is, it has some active processes that are
+     * all in the cached state.  It should be doing as little as possible at this point.
+     * If false, that a uid is no longer cached.  This will only be called after
+     * onUidCached() has been reported true.  It will happen when either one of its actively
+     * running processes is no longer cached, or it no longer has any actively running processes.
+     */
+    void onUidCachedChanged(int uid, boolean cached);
 }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 79e5407..b38be66 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -97,7 +97,6 @@
     private String mAppDir;
     private String mResDir;
     private String[] mOverlayDirs;
-    private String[] mSharedLibraries;
     private String mDataDir;
     private String mLibDir;
     private File mDataDirFile;
@@ -116,6 +115,7 @@
     private String[] mSplitNames;
     private String[] mSplitAppDirs;
     private String[] mSplitResDirs;
+    private String[] mSplitClassLoaderNames;
 
     private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
         = new ArrayMap<>();
@@ -126,8 +126,6 @@
     private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
         = new ArrayMap<>();
 
-    int mClientCount = 0;
-
     Application getApplication() {
         return mApplication;
     }
@@ -192,8 +190,8 @@
         mResDir = null;
         mSplitAppDirs = null;
         mSplitResDirs = null;
+        mSplitClassLoaderNames = null;
         mOverlayDirs = null;
-        mSharedLibraries = null;
         mDataDir = null;
         mDataDirFile = null;
         mDeviceProtectedDataDirFile = null;
@@ -324,7 +322,6 @@
         mAppDir = aInfo.sourceDir;
         mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
         mOverlayDirs = aInfo.resourceDirs;
-        mSharedLibraries = aInfo.sharedLibraryFiles;
         mDataDir = aInfo.dataDir;
         mLibDir = aInfo.nativeLibraryDir;
         mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
@@ -334,6 +331,7 @@
         mSplitNames = aInfo.splitNames;
         mSplitAppDirs = aInfo.splitSourceDirs;
         mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
+        mSplitClassLoaderNames = aInfo.splitClassLoaderNames;
 
         if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) {
             mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies);
@@ -530,7 +528,8 @@
             // Since we handled the special base case above, parentSplitIdx is always valid.
             final ClassLoader parent = mCachedClassLoaders[parentSplitIdx];
             mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader(
-                    mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent);
+                    mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent,
+                    mSplitClassLoaderNames[splitIdx - 1]);
 
             Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]);
             splitPaths.add(mSplitResDirs[splitIdx - 1]);
@@ -650,8 +649,9 @@
             if (mClassLoader == null) {
                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
                 mClassLoader = ApplicationLoaders.getDefault().getClassLoader(
-                    "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
-                    librarySearchPath, libraryPermittedPath, mBaseClassLoader);
+                        "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
+                        librarySearchPath, libraryPermittedPath, mBaseClassLoader,
+                        null /* classLoaderName */);
                 StrictMode.setThreadPolicy(oldPolicy);
             }
 
@@ -678,7 +678,8 @@
 
             mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip,
                     mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
-                    libraryPermittedPath, mBaseClassLoader);
+                    libraryPermittedPath, mBaseClassLoader,
+                    mApplicationInfo.classLoaderName);
 
             StrictMode.setThreadPolicy(oldPolicy);
             // Setup the class loader paths for profiling.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5a08cf3..a3377d7 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -561,6 +561,11 @@
     @SystemApi
     public static final int FLAG_AUTOGROUP_SUMMARY  = 0x00000400;
 
+    /**
+     * @hide
+     */
+    public static final int FLAG_CAN_COLORIZE = 0x00000800;
+
     public int flags;
 
     /** @hide */
@@ -2538,6 +2543,22 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public boolean hasCompletedProgress() {
+        // not a progress notification; can't be complete
+        if (!extras.containsKey(EXTRA_PROGRESS)
+                || !extras.containsKey(EXTRA_PROGRESS_MAX)) {
+            return false;
+        }
+        // many apps use max 0 for 'indeterminate'; not complete
+        if (extras.getInt(EXTRA_PROGRESS_MAX) == 0) {
+            return false;
+        }
+        return extras.getInt(EXTRA_PROGRESS) == extras.getInt(EXTRA_PROGRESS_MAX);
+    }
+
     /** @removed */
     @Deprecated
     public String getChannel() {
@@ -5174,7 +5195,16 @@
         if (isColorizedMedia()) {
             return true;
         }
-        return extras.getBoolean(EXTRA_COLORIZED) && isForegroundService();
+        return extras.getBoolean(EXTRA_COLORIZED)
+                && (hasColorizedPermission() || isForegroundService());
+    }
+
+    /**
+     * Returns whether an app can colorize due to the android.permission.USE_COLORIZED_NOTIFICATIONS
+     * permission. The permission is checked when a notification is enqueued.
+     */
+    private boolean hasColorizedPermission() {
+        return (flags & Notification.FLAG_CAN_COLORIZE) != 0;
     }
 
     /**
@@ -5234,7 +5264,7 @@
     }
 
     /**
-     * @hide
+     * @removed
      */
     @SystemApi
     public static Class<? extends Style> getNotificationStyleClass(String templateClass) {
diff --git a/core/java/android/app/ProgressDialog.java b/core/java/android/app/ProgressDialog.java
index 8ec9622..8a083eb 100644
--- a/core/java/android/app/ProgressDialog.java
+++ b/core/java/android/app/ProgressDialog.java
@@ -42,8 +42,12 @@
  *
  * <p>The progress range is 0 to {@link #getMax() max}.</p>
  *
- * @deprecated Use a progress indicator such as ProgressBar inline inside of
- * an activity rather than using this modal dialog.
+ * @deprecated <code>ProgressDialog</code> is a modal dialog, which prevents the
+ * user from interacting with the app. Instead of using this class, you should
+ * use a progress indicator like {@link android.widget.ProgressBar}, which can
+ * be embedded in your app's UI. Alternatively, you can use a
+ * <a href="/guide/topics/ui/notifiers/notifications.html">notification</a>
+ * to inform the user of the task's progress.
  */
 @Deprecated
 public class ProgressDialog extends AlertDialog {
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 063ad24..1758a06 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -778,7 +778,7 @@
             }
 
             long fsyncDuration = fsyncTime - writeTime;
-            mSyncTimes.add(Long.valueOf(fsyncDuration).intValue());
+            mSyncTimes.add((int) fsyncDuration);
             mNumSync++;
 
             if (DEBUG || mNumSync % 1024 == 0 || fsyncDuration > MAX_FSYNC_DURATION_MILLIS) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index f18aa58..ab70f0e7 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -83,6 +83,8 @@
 import android.net.NetworkScoreManager;
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
+import android.net.lowpan.ILowpanManager;
+import android.net.lowpan.LowpanManager;
 import android.net.wifi.IRttManager;
 import android.net.wifi.IWifiManager;
 import android.net.wifi.IWifiScanner;
@@ -540,6 +542,16 @@
                         ctx.mMainThread.getHandler());
             }});
 
+        registerService(Context.LOWPAN_SERVICE, LowpanManager.class,
+                new CachedServiceFetcher<LowpanManager>() {
+            @Override
+            public LowpanManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+                IBinder b = ServiceManager.getServiceOrThrow(Context.LOWPAN_SERVICE);
+                ILowpanManager service = ILowpanManager.Stub.asInterface(b);
+                return new LowpanManager(ctx.getOuterContext(), service,
+                        ConnectivityThread.getInstanceLooper());
+            }});
+
         registerService(Context.WIFI_SERVICE, WifiManager.class,
                 new CachedServiceFetcher<WifiManager>() {
             @Override
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index 8f172ba..b9d3e75 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -26,6 +26,7 @@
 import android.os.Parcelable;
 import android.util.Size;
 
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.graphics.palette.Palette;
 import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
 
@@ -36,16 +37,9 @@
 /**
  * Provides information about the colors of a wallpaper.
  * <p>
- * This class contains two main components:
- * <ul>
- * <li>Named colors: Most visually representative colors of a wallpaper. Can be either
+ * Exposes the 3 most visually representative colors of a wallpaper. Can be either
  * {@link WallpaperColors#getPrimaryColor()}, {@link WallpaperColors#getSecondaryColor()}
  * or {@link WallpaperColors#getTertiaryColor()}.
- * </li>
- * <li>Hints: How colors may affect other system components. Currently the only supported hint is
- * {@link WallpaperColors#HINT_SUPPORTS_DARK_TEXT}, which specifies if dark text is preferred
- * over the wallpaper.</li>
- * </ul>
  */
 public final class WallpaperColors implements Parcelable {
 
@@ -53,9 +47,18 @@
      * Specifies that dark text is preferred over the current wallpaper for best presentation.
      * <p>
      * eg. A launcher may set its text color to black if this flag is specified.
+     * @hide
      */
     public static final int HINT_SUPPORTS_DARK_TEXT = 0x1;
 
+    /**
+     * Specifies that dark theme is preferred over the current wallpaper for best presentation.
+     * <p>
+     * eg. A launcher may set its drawer color to black if this flag is specified.
+     * @hide
+     */
+    public static final int HINT_SUPPORTS_DARK_THEME = 0x2;
+
     // Maximum size that a bitmap can have to keep our calculations sane
     private static final int MAX_BITMAP_SIZE = 112;
 
@@ -67,8 +70,10 @@
     // present in at least MIN_COLOR_OCCURRENCE of the image
     private static final float MIN_COLOR_OCCURRENCE = 0.05f;
 
+    // Decides when dark theme is optimal for this wallpaper
+    private static final float DARK_THEME_MEAN_LUMINANCE = 0.25f;
     // Minimum mean luminosity that an image needs to have to support dark text
-    private static final float BRIGHT_IMAGE_MEAN_LUMINANCE = 0.9f;
+    private static final float BRIGHT_IMAGE_MEAN_LUMINANCE = 0.75f;
     // We also check if the image has dark pixels in it,
     // to avoid bright images with some dark spots.
     private static final float DARK_PIXEL_LUMINANCE = 0.45f;
@@ -91,9 +96,8 @@
     /**
      * Constructs {@link WallpaperColors} from a drawable.
      * <p>
-     * Main colors will be extracted from the drawable and hints will be calculated.
+     * Main colors will be extracted from the drawable.
      *
-     * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
      * @param drawable Source where to extract from.
      */
     public static WallpaperColors fromDrawable(Drawable drawable) {
@@ -122,9 +126,8 @@
     /**
      * Constructs {@link WallpaperColors} from a bitmap.
      * <p>
-     * Main colors will be extracted from the bitmap and hints will be calculated.
+     * Main colors will be extracted from the bitmap.
      *
-     * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
      * @param bitmap Source where to extract from.
      */
     public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap) {
@@ -177,14 +180,25 @@
             }
         }
 
-        int hints = 0;
-        if (calculateDarkTextSupport(bitmap)) {
-            hints |= HINT_SUPPORTS_DARK_TEXT;
-        }
+        int hints = calculateHints(bitmap);
         return new WallpaperColors(primary, secondary, tertiary, hints);
     }
 
     /**
+     * Constructs a new object from three colors.
+     *
+     * @param primaryColor Primary color.
+     * @param secondaryColor Secondary color.
+     * @param tertiaryColor Tertiary color.
+     * @see WallpaperColors#fromBitmap(Bitmap)
+     * @see WallpaperColors#fromDrawable(Drawable)
+     */
+    public WallpaperColors(@NonNull Color primaryColor, @Nullable Color secondaryColor,
+            @Nullable Color tertiaryColor) {
+        this(primaryColor, secondaryColor, tertiaryColor, 0);
+    }
+
+    /**
      * Constructs a new object from three colors, where hints can be specified.
      *
      * @param primaryColor Primary color.
@@ -194,6 +208,7 @@
      * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
      * @see WallpaperColors#fromBitmap(Bitmap)
      * @see WallpaperColors#fromDrawable(Drawable)
+     * @hide
      */
     public WallpaperColors(@NonNull Color primaryColor, @Nullable Color secondaryColor,
             @Nullable Color tertiaryColor, int colorHints) {
@@ -307,6 +322,7 @@
      *
      * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
      * @return True if dark text is supported.
+     * @hide
      */
     public int getColorHints() {
         return mColorHints;
@@ -327,9 +343,9 @@
      * @param source What to read.
      * @return Whether image supports dark text or not.
      */
-    private static boolean calculateDarkTextSupport(Bitmap source) {
+    private static int calculateHints(Bitmap source) {
         if (source == null) {
-            return false;
+            return 0;
         }
 
         int[] pixels = new int[source.getWidth() * source.getHeight()];
@@ -341,22 +357,29 @@
 
         // This bitmap was already resized to fit the maximum allowed area.
         // Let's just loop through the pixels, no sweat!
+        float[] tmpHsl = new float[3];
         for (int i = 0; i < pixels.length; i++) {
-            final float luminance = Color.luminance(pixels[i]);
+            ColorUtils.colorToHSL(pixels[i], tmpHsl);
+            final float luminance = tmpHsl[2];
             final int alpha = Color.alpha(pixels[i]);
-
             // Make sure we don't have a dark pixel mass that will
             // make text illegible.
             if (luminance < DARK_PIXEL_LUMINANCE && alpha != 0) {
                 darkPixels++;
-                if (darkPixels > maxDarkPixels) {
-                    return false;
-                }
             }
-
             totalLuminance += luminance;
         }
-        return totalLuminance / pixels.length > BRIGHT_IMAGE_MEAN_LUMINANCE;
+
+        int hints = 0;
+        double meanLuminance = totalLuminance / pixels.length;
+        if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels < maxDarkPixels) {
+            hints |= HINT_SUPPORTS_DARK_TEXT;
+        }
+        if (meanLuminance < DARK_THEME_MEAN_LUMINANCE) {
+            hints |= HINT_SUPPORTS_DARK_THEME;
+        }
+
+        return hints;
     }
 
     private static Size calculateOptimalSize(int width, int height) {
diff --git a/core/java/android/app/admin/ConnectEvent.java b/core/java/android/app/admin/ConnectEvent.java
index 423ee52..ffd38e2 100644
--- a/core/java/android/app/admin/ConnectEvent.java
+++ b/core/java/android/app/admin/ConnectEvent.java
@@ -23,7 +23,11 @@
 import java.net.UnknownHostException;
 
 /**
- * A class that represents a connect library call event.
+ * A class that represents a TCP connect event initiated through the standard network stack.
+ *
+ * <p>It contains information about the originating app as well as the remote TCP endpoint.
+ *
+ * <p>Support both IPv4 and IPv6 connections.
  */
 public final class ConnectEvent extends NetworkEvent implements Parcelable {
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f612eaa..c4d22a3 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5981,6 +5981,13 @@
     public static final int MAKE_USER_EPHEMERAL = 0x0002;
 
     /**
+     * Flag used by {@link #createAndManageUser} to specify that the user should be created as a
+     * demo user.
+     * @hide
+     */
+    public static final int MAKE_USER_DEMO = 0x0004;
+
+    /**
      * Called by a device owner to create a user with the specified name and a given component of
      * the calling package as profile owner. The UserHandle returned by this method should not be
      * persisted as user handles are recycled as users are removed and created. If you need to
diff --git a/core/java/android/app/admin/DnsEvent.java b/core/java/android/app/admin/DnsEvent.java
index c21725f..f84c5b0 100644
--- a/core/java/android/app/admin/DnsEvent.java
+++ b/core/java/android/app/admin/DnsEvent.java
@@ -26,7 +26,10 @@
 import java.util.List;
 
 /**
- * A class that represents a DNS lookup event.
+ * A class that represents a DNS lookup event initiated through the standard network stack.
+ *
+ * <p>It contains information about the originating app as well as the DNS hostname and resolved
+ * IP addresses.
  */
 public final class DnsEvent extends NetworkEvent implements Parcelable {
 
diff --git a/core/java/android/app/usage/ExternalStorageStats.java b/core/java/android/app/usage/ExternalStorageStats.java
index d7e570f..f00e5c2 100644
--- a/core/java/android/app/usage/ExternalStorageStats.java
+++ b/core/java/android/app/usage/ExternalStorageStats.java
@@ -33,6 +33,7 @@
     /** {@hide} */ public long videoBytes;
     /** {@hide} */ public long imageBytes;
     /** {@hide} */ public long appBytes;
+    /** {@hide} */ public long obbBytes;
 
     /**
      * Return the total bytes used by all files in the shared/external storage
@@ -97,6 +98,11 @@
     }
 
     /** {@hide} */
+    public @BytesLong long getObbBytes() {
+        return obbBytes;
+    }
+
+    /** {@hide} */
     public ExternalStorageStats() {
     }
 
@@ -107,6 +113,7 @@
         this.videoBytes = in.readLong();
         this.imageBytes = in.readLong();
         this.appBytes = in.readLong();
+        this.obbBytes = in.readLong();
     }
 
     @Override
@@ -121,6 +128,7 @@
         dest.writeLong(videoBytes);
         dest.writeLong(imageBytes);
         dest.writeLong(appBytes);
+        dest.writeLong(obbBytes);
     }
 
     public static final Creator<ExternalStorageStats> CREATOR = new Creator<ExternalStorageStats>() {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 27b802e..a206b53 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1758,6 +1758,38 @@
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                      BluetoothGattCallback callback, int transport, int phy,
                                      Handler handler) {
+        return connectGatt(context, autoConnect, callback, transport, false, phy, handler);
+    }
+
+    /**
+     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
+     * The callback is used to deliver results to Caller, such as connection status as well
+     * as any further GATT client operations.
+     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
+     * GATT client operations.
+     * @param callback GATT callback handler that will receive asynchronous callbacks.
+     * @param autoConnect Whether to directly connect to the remote device (false)
+     *                    or to automatically connect as soon as the remote
+     *                    device becomes available (true).
+     * @param transport preferred transport for GATT connections to remote dual-mode devices
+     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
+     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+     * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
+     *                      does not hold a GATT connection. It automatically disconnects when no
+     *                      other GATT connections are active for the remote device.
+     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
+     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+     *             an d{@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
+     *             if {@code autoConnect} is set to true.
+     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen
+     *             on an un-specified background thread.
+     * @return A BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client
+     *         operations.
+     * @hide
+     */
+    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+                                     BluetoothGattCallback callback, int transport,
+                                     boolean opportunistic, int phy, Handler handler) {
         if (callback == null)
             throw new NullPointerException("callback is null");
 
@@ -1771,7 +1803,7 @@
                 // BLE is not supported
                 return null;
             }
-            BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, phy);
+            BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, opportunistic, phy);
             gatt.connect(autoConnect, callback, handler);
             return gatt;
         } catch (RemoteException e) {Log.e(TAG, "", e);}
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index a3d6e9f..678159b 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -53,6 +53,7 @@
     private Boolean mDeviceBusy = false;
     private int mTransport;
     private int mPhy;
+    private boolean mOpportunistic;
 
     private static final int AUTH_RETRY_STATE_IDLE = 0;
     private static final int AUTH_RETRY_STATE_NO_MITM = 1;
@@ -172,7 +173,7 @@
                 }
                 try {
                     mService.clientConnect(mClientIf, mDevice.getAddress(),
-                                           !mAutoConnect, mTransport, mPhy); // autoConnect is inverse of "isDirect"
+                                           !mAutoConnect, mTransport, mOpportunistic, mPhy); // autoConnect is inverse of "isDirect"
                 } catch (RemoteException e) {
                     Log.e(TAG,"",e);
                 }
@@ -628,11 +629,12 @@
         };
 
     /*package*/ BluetoothGatt(IBluetoothGatt iGatt, BluetoothDevice device,
-                                int transport, int phy) {
+                                int transport, boolean opportunistic, int phy) {
         mService = iGatt;
         mDevice = device;
         mTransport = transport;
         mPhy = phy;
+        mOpportunistic = opportunistic;
         mServices = new ArrayList<BluetoothGattService>();
 
         mConnState = CONN_STATE_IDLE;
@@ -839,8 +841,8 @@
      */
     public boolean connect() {
         try {
-            mService.clientConnect(mClientIf, mDevice.getAddress(),
-                                   false, mTransport, mPhy); // autoConnect is inverse of "isDirect"
+            mService.clientConnect(mClientIf, mDevice.getAddress(), false, mTransport,
+                    mOpportunistic, mPhy); // autoConnect is inverse of "isDirect"
             return true;
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 167f5e9..e87f070 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -74,7 +74,7 @@
     void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
 
     void unregisterClient(in int clientIf);
-    void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport, in int phy);
+    void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport, in boolean opportunistic, in int phy);
     void clientDisconnect(in int clientIf, in String address);
     void clientSetPreferredPhy(in int clientIf, in String address, in int txPhy, in int rxPhy, in int phyOptions);
     void clientReadPhy(in int clientIf, in String address);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 128d195..63a2cf0 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2900,6 +2900,7 @@
             WIFI_AWARE_SERVICE,
             WIFI_P2P_SERVICE,
             WIFI_SCANNING_SERVICE,
+            //@hide: LOWPAN_SERVICE,
             //@hide: WIFI_RTT_SERVICE,
             //@hide: ETHERNET_SERVICE,
             WIFI_RTT_SERVICE,
@@ -2955,7 +2956,8 @@
             SHORTCUT_SERVICE,
             //@hide: CONTEXTHUB_SERVICE,
             SYSTEM_HEALTH_SERVICE,
-            //@hide: INCIDENT_SERVICE
+            //@hide: INCIDENT_SERVICE,
+            COMPANION_DEVICE_SERVICE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceName {}
@@ -3428,6 +3430,18 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
+     * android.net.lowpan.LowpanManager} for handling management of
+     * LoWPAN access.
+     *
+     * @see #getSystemService
+     * @see android.net.lowpan.LowpanManager
+     *
+     * @hide
+     */
+    public static final String LOWPAN_SERVICE = "lowpan";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a {@link
      * android.net.EthernetManager} for handling management of
      * Ethernet access.
      *
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 06f7916..0bfe567 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1005,6 +1005,12 @@
         }
     }
 
+    /** @hide */
+    public String classLoaderName;
+
+    /** @hide */
+    public String[] splitClassLoaderNames;
+
     public void dump(Printer pw, String prefix) {
         dump(pw, prefix, DUMP_FLAG_ALL);
     }
@@ -1056,6 +1062,13 @@
                 pw.println(prefix + "sharedLibraryFiles=" + Arrays.toString(sharedLibraryFiles));
             }
         }
+        if (classLoaderName != null) {
+            pw.println(prefix + "classLoaderName=" + classLoaderName);
+        }
+        if (!ArrayUtils.isEmpty(splitClassLoaderNames)) {
+            pw.println(prefix + "splitClassLoaderNames=" + Arrays.toString(splitClassLoaderNames));
+        }
+
         pw.println(prefix + "enabled=" + enabled
                 + " minSdkVersion=" + minSdkVersion
                 + " targetSdkVersion=" + targetSdkVersion
@@ -1178,6 +1191,8 @@
         networkSecurityConfigRes = orig.networkSecurityConfigRes;
         category = orig.category;
         targetSandboxVersion = orig.targetSandboxVersion;
+        classLoaderName = orig.classLoaderName;
+        splitClassLoaderNames = orig.splitClassLoaderNames;
     }
 
     public String toString() {
@@ -1246,6 +1261,8 @@
         dest.writeInt(networkSecurityConfigRes);
         dest.writeInt(category);
         dest.writeInt(targetSandboxVersion);
+        dest.writeString(classLoaderName);
+        dest.writeStringArray(splitClassLoaderNames);
     }
 
     public static final Parcelable.Creator<ApplicationInfo> CREATOR
@@ -1311,6 +1328,8 @@
         networkSecurityConfigRes = source.readInt();
         category = source.readInt();
         targetSandboxVersion = source.readInt();
+        classLoaderName = source.readString();
+        splitClassLoaderNames = source.readStringArray();
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b8e751e..827711a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2294,6 +2294,14 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports LoWPAN networking.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_LOWPAN = "android.hardware.lowpan";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: This is a device dedicated to showing UI
      * on a vehicle headunit. A headunit here is defined to be inside a
      * vehicle that may or may not be moving. A headunit uses either a
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e4f2fc1..eb6e0d8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -88,6 +88,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.ClassLoaderFactory;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
 
@@ -415,9 +416,12 @@
         public final boolean extractNativeLibs;
         public final boolean isolatedSplits;
 
+        public final String classLoaderName;
+        public final String[] splitClassLoaderNames;
+
         public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
                 boolean[] isFeatureSplits, String[] usesSplitNames, String[] configForSplit,
-                String[] splitCodePaths, int[] splitRevisionCodes) {
+                String[] splitCodePaths, int[] splitRevisionCodes, String[] splitClassLoaderNames) {
             this.packageName = baseApk.packageName;
             this.versionCode = baseApk.versionCode;
             this.installLocation = baseApk.installLocation;
@@ -437,6 +441,9 @@
             this.use32bitAbi = baseApk.use32bitAbi;
             this.extractNativeLibs = baseApk.extractNativeLibs;
             this.isolatedSplits = baseApk.isolatedSplits;
+
+            this.classLoaderName = baseApk.classLoaderName;
+            this.splitClassLoaderNames = splitClassLoaderNames;
         }
 
         public List<String> getAllCodePaths() {
@@ -471,13 +478,14 @@
         public final boolean use32bitAbi;
         public final boolean extractNativeLibs;
         public final boolean isolatedSplits;
+        public final String classLoaderName;
 
         public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit,
                 String configForSplit, String usesSplitName, int versionCode, int revisionCode,
                 int installLocation, List<VerifierInfo> verifiers, Signature[] signatures,
                 Certificate[][] certificates, boolean coreApp, boolean debuggable,
                 boolean multiArch, boolean use32bitAbi, boolean extractNativeLibs,
-                boolean isolatedSplits) {
+                boolean isolatedSplits, String classLoaderName) {
             this.codePath = codePath;
             this.packageName = packageName;
             this.splitName = splitName;
@@ -496,6 +504,7 @@
             this.use32bitAbi = use32bitAbi;
             this.extractNativeLibs = extractNativeLibs;
             this.isolatedSplits = isolatedSplits;
+            this.classLoaderName = classLoaderName;
         }
     }
 
@@ -863,7 +872,7 @@
         final ApkLite baseApk = parseApkLite(packageFile, flags);
         final String packagePath = packageFile.getAbsolutePath();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        return new PackageLite(packagePath, baseApk, null, null, null, null, null, null);
+        return new PackageLite(packagePath, baseApk, null, null, null, null, null, null, null);
     }
 
     static PackageLite parseClusterPackageLite(File packageDir, int flags)
@@ -926,6 +935,7 @@
         String[] configForSplits = null;
         String[] splitCodePaths = null;
         int[] splitRevisionCodes = null;
+        String[] splitClassLoaderNames = null;
         if (size > 0) {
             splitNames = new String[size];
             isFeatureSplits = new boolean[size];
@@ -933,6 +943,7 @@
             configForSplits = new String[size];
             splitCodePaths = new String[size];
             splitRevisionCodes = new int[size];
+            splitClassLoaderNames = new String[size];
 
             splitNames = apks.keySet().toArray(splitNames);
             Arrays.sort(splitNames, sSplitNameComparator);
@@ -944,12 +955,13 @@
                 configForSplits[i] = apk.configForSplit;
                 splitCodePaths[i] = apk.codePath;
                 splitRevisionCodes[i] = apk.revisionCode;
+                splitClassLoaderNames[i] = apk.classLoaderName;
             }
         }
 
         final String codePath = packageDir.getAbsolutePath();
         return new PackageLite(codePath, baseApk, splitNames, isFeatureSplits, usesSplitNames,
-                configForSplits, splitCodePaths, splitRevisionCodes);
+                configForSplits, splitCodePaths, splitRevisionCodes, splitClassLoaderNames);
     }
 
     /**
@@ -1187,6 +1199,8 @@
                 pkg.splitPrivateFlags = new int[num];
                 pkg.applicationInfo.splitNames = pkg.splitNames;
                 pkg.applicationInfo.splitDependencies = splitDependencies;
+                pkg.applicationInfo.classLoaderName = lite.classLoaderName;
+                pkg.applicationInfo.splitClassLoaderNames = lite.splitClassLoaderNames;
 
                 for (int i = 0; i < num; i++) {
                     final AssetManager splitAssets = assetLoader.getSplitAssetManager(i);
@@ -1697,7 +1711,7 @@
             }
 
             final AttributeSet attrs = parser;
-            return parseApkLite(apkPath, parser, attrs, flags, signatures, certificates);
+            return parseApkLite(apkPath, parser, attrs, signatures, certificates);
 
         } catch (XmlPullParserException | IOException | RuntimeException e) {
             Slog.w(TAG, "Failed to parse " + apkPath, e);
@@ -1784,7 +1798,7 @@
     }
 
     private static ApkLite parseApkLite(String codePath, XmlPullParser parser, AttributeSet attrs,
-            int flags, Signature[] signatures, Certificate[][] certificates)
+            Signature[] signatures, Certificate[][] certificates)
             throws IOException, XmlPullParserException, PackageParserException {
         final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
 
@@ -1800,6 +1814,7 @@
         boolean isFeatureSplit = false;
         String configForSplit = null;
         String usesSplitName = null;
+        String classLoaderName = null;
 
         for (int i = 0; i < attrs.getAttributeCount(); i++) {
             final String attr = attrs.getAttributeName(i);
@@ -1856,6 +1871,14 @@
                     if ("extractNativeLibs".equals(attr)) {
                         extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
                     }
+                    if ("classLoader".equals(attr)) {
+                        classLoaderName = attrs.getAttributeValue(i);
+                        if (!ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
+                            throw new PackageParserException(
+                                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+                                    "Invalid class loader name: " + classLoaderName);
+                        }
+                    }
                 }
             } else if (TAG_USES_SPLIT.equals(parser.getName())) {
                 if (usesSplitName != null) {
@@ -1875,19 +1898,7 @@
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
                 configForSplit, usesSplitName, versionCode, revisionCode, installLocation,
                 verifiers, signatures, certificates, coreApp, debuggable, multiArch, use32bitAbi,
-                extractNativeLibs, isolatedSplits);
-    }
-
-    /**
-     * Temporary.
-     */
-    static public Signature stringToSignature(String str) {
-        final int N = str.length();
-        byte[] sig = new byte[N];
-        for (int i=0; i<N; i++) {
-            sig[i] = (byte)str.charAt(i);
-        }
-        return new Signature(sig);
+                extractNativeLibs, isolatedSplits, classLoaderName);
     }
 
     /**
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index be31d1b..ef279b8 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1291,7 +1291,7 @@
             changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
             setAppBounds(delta.appBounds);
         }
-        if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED) {
+        if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED && delta.assetsSeq != assetsSeq) {
             changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
             assetsSeq = delta.assetsSeq;
         }
@@ -1672,7 +1672,24 @@
         n = this.densityDpi - that.densityDpi;
         if (n != 0) return n;
         n = this.assetsSeq - that.assetsSeq;
-        //if (n != 0) return n;
+        if (n != 0) return n;
+
+        if (this.appBounds == null && that.appBounds != null) {
+            return 1;
+        } else if (this.appBounds != null && that.appBounds == null) {
+            return -1;
+        } else if (this.appBounds != null && that.appBounds != null) {
+            n = this.appBounds.left - that.appBounds.left;
+            if (n != 0) return n;
+            n = this.appBounds.top - that.appBounds.top;
+            if (n != 0) return n;
+            n = this.appBounds.right - that.appBounds.right;
+            if (n != 0) return n;
+            n = this.appBounds.bottom - that.appBounds.bottom;
+            if (n != 0) return n;
+        }
+
+        // if (n != 0) return n;
         return n;
     }
 
diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java
index 5f01e30..4795e97 100644
--- a/core/java/android/database/ContentObserver.java
+++ b/core/java/android/database/ContentObserver.java
@@ -193,6 +193,11 @@
      */
     private void dispatchChange(boolean selfChange, Uri uri, int userId) {
         if (mHandler == null) {
+            synchronized (mLock) {
+                if (mTransport == null) {
+                    return;
+                }
+            }
             onChange(selfChange, uri, userId);
         } else {
             mHandler.post(new NotificationRunnable(selfChange, uri, userId));
@@ -213,6 +218,11 @@
 
         @Override
         public void run() {
+            synchronized (mLock) {
+                if (mTransport == null) {
+                    return;
+                }
+            }
             ContentObserver.this.onChange(mSelfChange, mUri, mUserId);
         }
     }
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 3a1714c..cba7303 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -16,8 +16,7 @@
 
 package android.database.sqlite;
 
-import dalvik.system.CloseGuard;
-
+import android.app.ActivityManager;
 import android.database.sqlite.SQLiteDebug.DbStats;
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
@@ -26,6 +25,8 @@
 import android.util.PrefixPrinter;
 import android.util.Printer;
 
+import dalvik.system.CloseGuard;
+
 import java.io.Closeable;
 import java.util.ArrayList;
 import java.util.Map;
@@ -147,6 +148,11 @@
 
     private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
         mConfiguration = new SQLiteDatabaseConfiguration(configuration);
+        // Disable lookaside allocator on low-RAM devices
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            mConfiguration.lookasideSlotCount = 0;
+            mConfiguration.lookasideSlotSize = 0;
+        }
         setMaxConnectionPoolSizeLocked();
     }
 
@@ -1004,7 +1010,10 @@
             printer.println("Connection pool for " + mConfiguration.path + ":");
             printer.println("  Open: " + mIsOpen);
             printer.println("  Max connections: " + mMaxConnectionPoolSize);
-
+            if (mConfiguration.isLookasideConfigSet()) {
+                printer.println("  Lookaside config: sz=" + mConfiguration.lookasideSlotSize
+                        + " cnt=" + mConfiguration.lookasideSlotCount);
+            }
             printer.println("  Available primary connection:");
             if (mAvailablePrimaryConnection != null) {
                 mAvailablePrimaryConnection.dump(indentedPrinter, verbose);
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 7406b3f..ea2b89e 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -2366,6 +2366,10 @@
              * <p>SQLite default settings will be used, if this method isn't called.
              * Use {@code setLookasideConfig(0,0)} to disable lookaside
              *
+             * <p><strong>Note:</strong> Provided slotSize/slotCount configuration is just a
+             * recommendation. The system may choose different values depending on a device, e.g.
+             * lookaside allocations can be disabled on low-RAM devices
+             *
              * @param slotSize The size in bytes of each lookaside slot.
              * @param slotCount The total number of lookaside memory slots per database connection.
              */
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 1435c83..7f09b73 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -180,4 +180,8 @@
         }
         return EMAIL_IN_DB_PATTERN.matcher(path).replaceAll("XX@YY");
     }
+
+    boolean isLookasideConfigSet() {
+        return lookasideSlotCount >= 0 && lookasideSlotSize >= 0;
+    }
 }
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 44a72dd..c19db82 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -176,6 +176,10 @@
      * <p>SQLite default settings will be used, if this method isn't called.
      * Use {@code setLookasideConfig(0,0)} to disable lookaside
      *
+     * <p><strong>Note:</strong> Provided slotSize/slotCount configuration is just a recommendation.
+     * The system may choose different values depending on a device, e.g. lookaside allocations
+     * can be disabled on low-RAM devices
+     *
      * @param slotSize The size in bytes of each lookaside slot.
      * @param slotCount The total number of lookaside memory slots per database connection.
      */
diff --git a/core/java/android/net/OWNERS b/core/java/android/net/OWNERS
new file mode 100644
index 0000000..0f1e259
--- /dev/null
+++ b/core/java/android/net/OWNERS
@@ -0,0 +1,6 @@
+ek@google.com
+hugobenichi@google.com
+jsharkey@google.com
+lorenzo@google.com
+satk@google.com
+silberst@google.com
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 7678678..218e4f2 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -253,6 +253,20 @@
                         Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
                     }
                     a.recycle();
+                } else if (eventType == XmlPullParser.START_TAG &&
+                        tagName.equals("aid-suffix-filter") && currentGroup != null) {
+                    final TypedArray a = res.obtainAttributes(attrs,
+                            com.android.internal.R.styleable.AidFilter);
+                    String aid = a.getString(com.android.internal.R.styleable.AidFilter_name).
+                            toUpperCase();
+                    // Add wildcard char to indicate suffix
+                    aid = aid.concat("#");
+                    if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) {
+                        currentGroup.aids.add(aid);
+                    } else {
+                        Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
+                    }
+                    a.recycle();
                 }
             }
         } catch (NameNotFoundException e) {
@@ -297,6 +311,17 @@
         return prefixAids;
     }
 
+    public List<String> getSubsetAids() {
+        final ArrayList<String> subsetAids = new ArrayList<String>();
+        for (AidGroup group : getAidGroups()) {
+            for (String aid : group.aids) {
+                if (aid.endsWith("#")) {
+                    subsetAids.add(aid);
+                }
+            }
+        }
+        return subsetAids;
+    }
     /**
      * Returns the registered AID group for this category.
      */
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index b49288e..6dd7993 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -606,6 +606,8 @@
      * <li>Consist of only hex characters
      * <li>Additionally, we allow an asterisk at the end, to indicate
      *     a prefix
+     * <li>Additinally we allow an (#) at symbol at the end, to indicate
+     *     a subset
      * </ul>
      *
      * @hide
@@ -614,20 +616,20 @@
         if (aid == null)
             return false;
 
-        // If a prefix AID, the total length must be odd (even # of AID chars + '*')
-        if (aid.endsWith("*") && ((aid.length() % 2) == 0)) {
+        // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*')
+        if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) {
             Log.e(TAG, "AID " + aid + " is not a valid AID.");
             return false;
         }
 
-        // If not a prefix AID, the total length must be even (even # of AID chars)
-        if (!aid.endsWith("*") && ((aid.length() % 2) != 0)) {
+        // If not a prefix/subset AID, the total length must be even (even # of AID chars)
+        if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) {
             Log.e(TAG, "AID " + aid + " is not a valid AID.");
             return false;
         }
 
         // Verify hex characters
-        if (!aid.matches("[0-9A-Fa-f]{10,32}\\*?")) {
+        if (!aid.matches("[0-9A-Fa-f]{10,32}\\*?\\#?")) {
             Log.e(TAG, "AID " + aid + " is not a valid AID.");
             return false;
         }
diff --git a/core/java/android/nfc/cardemulation/HostNfcFService.java b/core/java/android/nfc/cardemulation/HostNfcFService.java
index 27c4976..fd0d8ad 100644
--- a/core/java/android/nfc/cardemulation/HostNfcFService.java
+++ b/core/java/android/nfc/cardemulation/HostNfcFService.java
@@ -64,6 +64,7 @@
  *           android:description="@string/servicedesc"&gt;
  *       &lt;system-code-filter android:name="4000"/&gt;
  *       &lt;nfcid2-filter android:name="02FE000000000000"/&gt;
+         &lt;t3tPmm-filter android:name="FFFFFFFFFFFFFFFF"/&gt;
  * &lt;/host-nfcf-service&gt;
  * </pre>
  *
@@ -76,6 +77,7 @@
  * <ul>
  * <li>Exactly one {@link android.R.styleable#SystemCodeFilter &lt;system-code-filter&gt;} tag.</li>
  * <li>Exactly one {@link android.R.styleable#Nfcid2Filter &lt;nfcid2-filter&gt;} tag.</li>
+ * <li>Zero or one {@link android.R.styleable#T3tPmmFilter &lt;t3tPmm-filter&gt;} tag.</li>
  * </ul>
  * </p>
  *
diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
index b93eec1..4201935 100644
--- a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
@@ -18,9 +18,9 @@
 
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
@@ -80,11 +80,16 @@
     final int mUid;
 
     /**
+     * LF_T3T_PMM of the service
+     */
+    final String mT3tPmm;
+
+    /**
      * @hide
      */
     public NfcFServiceInfo(ResolveInfo info, String description,
             String systemCode, String dynamicSystemCode, String nfcid2, String dynamicNfcid2,
-            int uid) {
+            int uid, String t3tPmm) {
         this.mService = info;
         this.mDescription = description;
         this.mSystemCode = systemCode;
@@ -92,6 +97,7 @@
         this.mNfcid2 = nfcid2;
         this.mDynamicNfcid2 = dynamicNfcid2;
         this.mUid = uid;
+        this.mT3tPmm = t3tPmm;
     }
 
     public NfcFServiceInfo(PackageManager pm, ResolveInfo info)
@@ -130,6 +136,7 @@
 
             String systemCode = null;
             String nfcid2 = null;
+            String t3tPmm = null;
             final int depth = parser.getDepth();
 
             while (((eventType = parser.next()) != XmlPullParser.END_TAG ||
@@ -160,10 +167,22 @@
                         nfcid2 = null;
                     }
                     a.recycle();
+                } else if (eventType == XmlPullParser.START_TAG && tagName.equals("t3tPmm-filter")
+                        && t3tPmm == null) {
+                    final TypedArray a = res.obtainAttributes(attrs,
+                            com.android.internal.R.styleable.T3tPmmFilter);
+                    t3tPmm = a.getString(
+                            com.android.internal.R.styleable.T3tPmmFilter_name).toUpperCase();
+                    if (t3tPmm == null) {
+                        String defaultT3tPmm = "FFFFFFFFFFFFFFFF";
+                        t3tPmm = defaultT3tPmm;
+                    }
+                    a.recycle();
                 }
             }
             mSystemCode = (systemCode == null ? "NULL" : systemCode);
             mNfcid2 = (nfcid2 == null ? "NULL" : nfcid2);
+            mT3tPmm = (t3tPmm == null ? "NULL" : t3tPmm);
         } catch (NameNotFoundException e) {
             throw new XmlPullParserException("Unable to create context for: " + si.packageName);
         } finally {
@@ -202,6 +221,10 @@
         return mUid;
     }
 
+    public String getT3tPmm() {
+        return mT3tPmm;
+    }
+
     public CharSequence loadLabel(PackageManager pm) {
         return mService.loadLabel(pm);
     }
@@ -223,6 +246,7 @@
         if (mDynamicNfcid2 != null) {
             out.append(", dynamic NFCID2: " + mDynamicNfcid2);
         }
+        out.append(", T3T PMM:" + mT3tPmm);
         return out.toString();
     }
 
@@ -235,7 +259,7 @@
         if (!thatService.getComponent().equals(this.getComponent())) return false;
         if (!thatService.mSystemCode.equalsIgnoreCase(this.mSystemCode)) return false;
         if (!thatService.mNfcid2.equalsIgnoreCase(this.mNfcid2)) return false;
-
+        if (!thatService.mT3tPmm.equalsIgnoreCase(this.mT3tPmm)) return false;
         return true;
     }
 
@@ -264,6 +288,7 @@
             dest.writeString(mDynamicNfcid2);
         }
         dest.writeInt(mUid);
+        dest.writeString(mT3tPmm);
     };
 
     public static final Parcelable.Creator<NfcFServiceInfo> CREATOR =
@@ -283,8 +308,9 @@
                 dynamicNfcid2 = source.readString();
             }
             int uid = source.readInt();
+            String t3tPmm = source.readString();
             NfcFServiceInfo service = new NfcFServiceInfo(info, description,
-                    systemCode, dynamicSystemCode, nfcid2, dynamicNfcid2, uid);
+                    systemCode, dynamicSystemCode, nfcid2, dynamicNfcid2, uid, t3tPmm);
             return service;
         }
 
@@ -299,6 +325,7 @@
                 " (Description: " + getDescription() + ")");
         pw.println("    System Code: " + getSystemCode());
         pw.println("    NFCID2: " + getNfcid2());
+        pw.println("    T3tPmm: " + getT3tPmm());
     }
 }
 
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 801c002..10331b9 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -132,7 +132,7 @@
  * caller of the read function must know what type to expect and pass in the
  * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
  * properly construct the new object and read its data.  (To more efficient
- * write and read a single Parceable object that is not null, you can directly
+ * write and read a single Parcelable object that is not null, you can directly
  * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
  * yourself.)</p>
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 6f458e0..2c6c7f9 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -87,19 +87,19 @@
     /** Send progress to listeners no more often than this (in ms). */
     private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
 
-    private static final long DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS = 30000L; // 30 s
+    private static final long DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 30000L; // 30 s
 
-    private static final long MIN_EUICC_WIPING_TIMEOUT_MILLIS = 5000L; // 5 s
+    private static final long MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 5000L; // 5 s
 
-    private static final long MAX_EUICC_WIPING_TIMEOUT_MILLIS = 60000L; // 60 s
+    private static final long MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 60000L; // 60 s
 
     /** Used to communicate with recovery.  See bootable/recovery/recovery.cpp. */
     private static final File RECOVERY_DIR = new File("/cache/recovery");
     private static final File LOG_FILE = new File(RECOVERY_DIR, "log");
     private static final File LAST_INSTALL_FILE = new File(RECOVERY_DIR, "last_install");
     private static final String LAST_PREFIX = "last_";
-    private static final String ACTION_WIPE_EUICC_DATA =
-            "com.android.internal.action.WIPE_EUICC_DATA";
+    private static final String ACTION_EUICC_FACTORY_RESET =
+            "com.android.internal.action.EUICC_FACTORY_RESET";
 
     /**
      * The recovery image uses this file to identify the location (i.e. blocks)
@@ -751,9 +751,7 @@
         // Block until the ordered broadcast has completed.
         condition.block();
 
-        if (wipeEuicc) {
-            wipeEuiccData(context);
-        }
+        wipeEuiccData(context, wipeEuicc);
 
         String shutdownArg = null;
         if (shutdown) {
@@ -769,7 +767,7 @@
         bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
     }
 
-    private static void wipeEuiccData(Context context) {
+    private static void wipeEuiccData(Context context, final boolean isWipeEuicc) {
         EuiccManager euiccManager = (EuiccManager) context.getSystemService(
                 Context.EUICC_SERVICE);
         if (euiccManager != null && euiccManager.isEnabled()) {
@@ -778,48 +776,69 @@
             BroadcastReceiver euiccWipeFinishReceiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
-                    if (ACTION_WIPE_EUICC_DATA.equals(intent.getAction())) {
+                    if (ACTION_EUICC_FACTORY_RESET.equals(intent.getAction())) {
                         if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
                             int detailedCode = intent.getIntExtra(
                                     EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
-                            Log.e(TAG, "Error wiping euicc data, Detailed code = "
-                                    + detailedCode);
+                            if (isWipeEuicc) {
+                                Log.e(TAG, "Error wiping euicc data, Detailed code = "
+                                        + detailedCode);
+                            } else {
+                                Log.e(TAG, "Error retaining euicc data, Detailed code = "
+                                        + detailedCode);
+                            }
                         } else {
-                            Log.d(TAG, "Successfully wiped euicc data.");
+                            if (isWipeEuicc) {
+                                Log.d(TAG, "Successfully wiped euicc data.");
+                            } else {
+                                Log.d(TAG, "Successfully retained euicc data.");
+                            }
                         }
                         euiccFactoryResetLatch.countDown();
                     }
                 }
             };
 
-            Intent intent = new Intent(ACTION_WIPE_EUICC_DATA);
+            Intent intent = new Intent(ACTION_EUICC_FACTORY_RESET);
             intent.setPackage("android");
             PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser(
                     context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM);
             IntentFilter filterConsent = new IntentFilter();
-            filterConsent.addAction(ACTION_WIPE_EUICC_DATA);
+            filterConsent.addAction(ACTION_EUICC_FACTORY_RESET);
             HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread");
             euiccHandlerThread.start();
             Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
             context.registerReceiver(euiccWipeFinishReceiver, filterConsent, null, euiccHandler);
-            euiccManager.eraseSubscriptions(callbackIntent);
+            if (isWipeEuicc) {
+                euiccManager.eraseSubscriptions(callbackIntent);
+            } else {
+                euiccManager.retainSubscriptionsForFactoryReset(callbackIntent);
+            }
             try {
                 long waitingTimeMillis = Settings.Global.getLong(
                         context.getContentResolver(),
-                        Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
-                        DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS);
-                if (waitingTimeMillis < MIN_EUICC_WIPING_TIMEOUT_MILLIS) {
-                    waitingTimeMillis = MIN_EUICC_WIPING_TIMEOUT_MILLIS;
-                } else if (waitingTimeMillis > MAX_EUICC_WIPING_TIMEOUT_MILLIS) {
-                    waitingTimeMillis = MAX_EUICC_WIPING_TIMEOUT_MILLIS;
+                        Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
+                        DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS);
+                if (waitingTimeMillis < MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS;
+                } else if (waitingTimeMillis > MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS) {
+                    waitingTimeMillis = MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS;
                 }
                 if (!euiccFactoryResetLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) {
-                    Log.e(TAG, "Timeout wiping eUICC data.");
+                    if (isWipeEuicc) {
+                        Log.e(TAG, "Timeout wiping eUICC data.");
+                    } else {
+                        Log.e(TAG, "Timeout retaining eUICC data.");
+                    }
                 }
                 context.unregisterReceiver(euiccWipeFinishReceiver);
             } catch (InterruptedException e) {
                 Thread.currentThread().interrupt();
-                Log.e(TAG, "Wiping eUICC data interrupted", e);
+                if (isWipeEuicc) {
+                    Log.e(TAG, "Wiping eUICC data interrupted", e);
+                } else {
+                    Log.e(TAG, "Retaining eUICC data interrupted", e);
+                }
             }
         }
     }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b710cf1..8e3e378 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7023,6 +7023,16 @@
                 "automatic_storage_manager_last_run";
 
         /**
+         * If the automatic storage manager has been disabled by policy. Note that this doesn't
+         * mean that the automatic storage manager is prevented from being re-enabled -- this only
+         * means that it was turned off by policy at least once.
+         *
+         * @hide
+         */
+        public static final String AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY =
+                "automatic_storage_manager_turned_off_by_policy";
+
+        /**
          * Whether SystemUI navigation keys is enabled.
          * @hide
          */
@@ -7181,6 +7191,10 @@
             VR_DISPLAY_MODE,
             NOTIFICATION_BADGING,
             QS_AUTO_ADDED_TILES,
+            SCREENSAVER_ENABLED,
+            SCREENSAVER_COMPONENTS,
+            SCREENSAVER_ACTIVATE_ON_DOCK,
+            SCREENSAVER_ACTIVATE_ON_SLEEP,
         };
 
         /** @hide */
@@ -10176,8 +10190,8 @@
          *
          * @hide
          */
-        public static final String EUICC_WIPING_TIMEOUT_MILLIS =
-                "euicc_wiping_timeout_millis";
+        public static final String EUICC_FACTORY_RESET_TIMEOUT_MILLIS =
+                "euicc_factory_reset_timeout_millis";
 
         /**
          * Settings to backup. This is here so that it's in the same place as the settings
diff --git a/core/java/android/provider/TimeZoneRulesDataContract.java b/core/java/android/provider/TimeZoneRulesDataContract.java
index 19e914b..3bddf2c 100644
--- a/core/java/android/provider/TimeZoneRulesDataContract.java
+++ b/core/java/android/provider/TimeZoneRulesDataContract.java
@@ -40,75 +40,96 @@
     private static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
 
     /**
-     * The content:// style URI for determining what type of update is available.
-     *
-     * <p>The URI can be queried using
-     * {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)};
-     * the result will be a cursor with a single row. If the {@link #COLUMN_OPERATION}
-     * column is {@link #OPERATION_INSTALL} then see {@link #DATA_URI} for how to obtain the
-     * binary data.
+     * Defines fields exposed through the {@link Operation#CONTENT_URI} for describing a time zone
+     * distro operation.
      */
-    public static final Uri OPERATION_URI = Uri.withAppendedPath(AUTHORITY_URI, "operation");
+    public static final class Operation {
+
+        /** Not instantiable. */
+        private Operation() {
+        }
+
+        /**
+         * The content:// style URI for determining what type of update is available.
+         *
+         * <p>The URI can be queried using
+         * {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)};
+         * the result will be a cursor with a single row. If the {@link Operation#TYPE}
+         * column is {@link Operation#TYPE_INSTALL} then see {@link Data#CONTENT_URI} for how
+         * to obtain the binary data.
+         */
+        public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "operation");
+
+        /**
+         * The {@code String} column of the {@link #CONTENT_URI} that provides an int specifying
+         * the type of operation to perform. See {@link #TYPE_NO_OP},
+         * {@link #TYPE_UNINSTALL} and {@link #TYPE_INSTALL}.
+         */
+        public static final String TYPE = "type";
+
+        /**
+         * An operation type used when the current time zone rules on device should be replaced by
+         * a new set obtained via the {@link android.content.ContentProvider#openFile(Uri, String)}
+         * method.
+         */
+        public static final String TYPE_INSTALL = "INSTALL";
+
+        /**
+         * An operation type used when the current time zone rules on device should be uninstalled,
+         * returning to the values held in the system partition.
+         */
+        public static final String TYPE_UNINSTALL = "UNINSTALL";
+
+        /**
+         * An operation type used when the time zone rules on device should be left as they are.
+         * This is not expected to be used in normal operation but a safe result in the event of an
+         * error that cannot be recovered from.
+         */
+        public static final String TYPE_NO_OP = "NOOP";
+
+        /**
+         * The {@code nullable int} column of the {@link #CONTENT_URI} that describes the major
+         * version of the distro to be installed.
+         * Only non-null if {@link #TYPE} contains {@link #TYPE_INSTALL}.
+         */
+        public static final String DISTRO_MAJOR_VERSION = "distro_major_version";
+
+        /**
+         * The {@code nullable int} column of the {@link #CONTENT_URI} that describes the minor
+         * version of the distro to be installed.
+         * Only non-null if {@link #TYPE} contains {@link #TYPE_INSTALL}.
+         */
+        public static final String DISTRO_MINOR_VERSION = "distro_minor_version";
+
+        /**
+         * The {@code nullable String} column of the {@link #CONTENT_URI} that describes the IANA
+         * rules version of the distro to be installed.
+         * Only non-null if {@link #TYPE} contains {@link #TYPE_INSTALL}.
+         */
+        public static final String RULES_VERSION = "rules_version";
+
+        /**
+         * The {@code nullable int} column of the {@link #CONTENT_URI} that describes the revision
+         * number of the distro to be installed.
+         * Only non-null if {@link #TYPE} contains {@link #TYPE_INSTALL}.
+         */
+        public static final String REVISION = "revision";
+    }
 
     /**
-     * The {@code String} column of the {@link #OPERATION_URI} that provides an int specifying the
-     * type of operation to perform. See {@link #OPERATION_NO_OP}, {@link #OPERATION_UNINSTALL} and
-     * {@link #OPERATION_INSTALL}.
+     * Defines the {@link Data#CONTENT_URI} for obtaining time zone distro binary data.
      */
-    public static final String COLUMN_OPERATION = "operation";
+    public static final class Data {
 
-    /**
-     * An operation type used when the time zone rules on device should be left as they are.
-     * This is not expected to be used in normal operation but a safe result in the event of an
-     * error that cannot be recovered from.
-     */
-    public static final String OPERATION_NO_OP = "NOOP";
+        /** Not instantiable. */
+        private Data() {
+        }
 
-    /**
-     * An operation type used when the current time zone rules on device should be uninstalled,
-     * returning to the values held in the system partition.
-     */
-    public static final String OPERATION_UNINSTALL = "UNINSTALL";
-
-    /**
-     * An operation type used when the current time zone rules on device should be replaced by
-     * a new set obtained via the {@link android.content.ContentProvider#openFile(Uri, String)}
-     * method.
-     */
-    public static final String OPERATION_INSTALL = "INSTALL";
-
-    /**
-     * The {@code nullable int} column of the {@link #OPERATION_URI} that describes the major
-     * version of the distro to be installed.
-     * Only non-null if {@link #COLUMN_OPERATION} contains {@link #OPERATION_INSTALL}.
-     */
-    public static final String COLUMN_DISTRO_MAJOR_VERSION = "distro_major_version";
-
-    /**
-     * The {@code nullable int} column of the {@link #OPERATION_URI} that describes the minor
-     * version of the distro to be installed.
-     * Only non-null if {@link #COLUMN_OPERATION} contains {@link #OPERATION_INSTALL}.
-     */
-    public static final String COLUMN_DISTRO_MINOR_VERSION = "distro_minor_version";
-
-    /**
-     * The {@code nullable String} column of the {@link #OPERATION_URI} that describes the IANA
-     * rules version of the distro to be installed.
-     * Only non-null if {@link #COLUMN_OPERATION} contains {@link #OPERATION_INSTALL}.
-     */
-    public static final String COLUMN_RULES_VERSION = "rules_version";
-
-    /**
-     * The {@code nullable int} column of the {@link #OPERATION_URI} that describes the revision
-     * number of the distro to be installed.
-     * Only non-null if {@link #COLUMN_OPERATION} contains {@link #OPERATION_INSTALL}.
-     */
-    public static final String COLUMN_REVISION = "revision";
-
-    /**
-     * The content:// style URI for obtaining time zone bundle data.
-     *
-     * <p>Use {@link android.content.ContentProvider#openFile(Uri, String)} with "r" mode.
-     */
-    public static final Uri DATA_URI = Uri.withAppendedPath(AUTHORITY_URI, "data");
+        /**
+         * The content:// style URI for obtaining time zone bundle data.
+         *
+         * <p>Use {@link android.content.ContentProvider#openFile(Uri, String)} with "r" mode.
+         */
+        public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "data");
+    }
 }
diff --git a/core/java/android/service/autofill/CharSequenceTransformation.java b/core/java/android/service/autofill/CharSequenceTransformation.java
index 7472aba..9d8345c 100644
--- a/core/java/android/service/autofill/CharSequenceTransformation.java
+++ b/core/java/android/service/autofill/CharSequenceTransformation.java
@@ -19,6 +19,7 @@
 import static android.view.autofill.Helper.sDebug;
 
 import android.annotation.NonNull;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArrayMap;
@@ -30,6 +31,8 @@
 
 import com.android.internal.util.Preconditions;
 
+import java.util.regex.Pattern;
+
 /**
  * Replaces a {@link TextView} child of a {@link CustomDescription} with the contents of one or
  * more regular expressions (regexs).
@@ -41,24 +44,20 @@
  * be:
  *
  * <pre class="prettyprint">
- * new CharSequenceTransformation.Builder()
- *   .addField(ccNumberId, "^.*(\\d\\d\\d\\d)$", "...$1")
- *   .build();
+ * new CharSequenceTransformation.Builder(ccNumberId, "^.*(\\d\\d\\d\\d)$", "...$1").build();
  * </pre>
  *
- * <p>But a tranformation that generates a {@code Exp: MM / YYYY} credit expiration date from two
+ * <p>But a transformation that generates a {@code Exp: MM / YYYY} credit expiration date from two
  * fields (month and year) would be:
  *
  * <pre class="prettyprint">
- * new CharSequenceTransformation.Builder()
- *   .addField(ccExpMonthId, "^(\\d\\d)$", "Exp: $1")
+ * new CharSequenceTransformation.Builder(ccExpMonthId, "^(\\d\\d)$", "Exp: $1")
  *   .addField(ccExpYearId, "^(\\d\\d\\d\\d)$", " / $1");
  * </pre>
  */
-//TODO(b/62534917): add unit tests
 public final class CharSequenceTransformation extends InternalTransformation implements Parcelable {
     private static final String TAG = "CharSequenceTransformation";
-    private final ArrayMap<AutofillId, Pair<String, String>> mFields;
+    @NonNull private final ArrayMap<AutofillId, Pair<Pattern, String>> mFields;
 
     private CharSequenceTransformation(Builder builder) {
         mFields = builder.mFields;
@@ -66,6 +65,7 @@
 
     /** @hide */
     @Override
+    @TestApi
     public void apply(@NonNull ValueFinder finder, @NonNull RemoteViews parentTemplate,
             int childViewId) {
         final StringBuilder converted = new StringBuilder();
@@ -73,14 +73,21 @@
         if (sDebug) Log.d(TAG, size + " multiple fields on id " + childViewId);
         for (int i = 0; i < size; i++) {
             final AutofillId id = mFields.keyAt(i);
-            final Pair<String, String> regex = mFields.valueAt(i);
+            final Pair<Pattern, String> regex = mFields.valueAt(i);
             final String value = finder.findByAutofillId(id);
             if (value == null) {
                 Log.w(TAG, "No value for id " + id);
                 return;
             }
-            final String convertedValue = value.replaceAll(regex.first, regex.second);
-            converted.append(convertedValue);
+            try {
+                // replaceAll throws an exception if the subst is invalid
+                final String convertedValue = regex.first.matcher(value).replaceAll(regex.second);
+                converted.append(convertedValue);
+            } catch (Exception e) {
+                // Do not log full exception to avoid leaks
+                Log.w(TAG, "Cannot apply " + regex.first.pattern() + "->" + regex.second + " to "
+                        + "field with autofill id" + id + ": " + e.getClass());
+            }
         }
         parentTemplate.setCharSequence(childViewId, "setText", converted);
     }
@@ -89,18 +96,32 @@
      * Builder for {@link CharSequenceTransformation} objects.
      */
     public static class Builder {
-        private ArrayMap<AutofillId, Pair<String, String>> mFields;
+        @NonNull private final ArrayMap<AutofillId, Pair<Pattern, String>> mFields =
+                new ArrayMap<>();
         private boolean mDestroyed;
 
-        //TODO(b/62534917): add constructor that takes a field so we force it to have at least one
-        // (and then remove the check for empty from build())
+        /**
+         * Creates a new builder and adds the first transformed contents of a field to the overall
+         * result of this transformation.
+         *
+         * @param id id of the screen field.
+         * @param regex regular expression with groups (delimited by {@code (} and {@code (}) that
+         * are used to substitute parts of the value. The pattern will be {@link Pattern#compile
+         * compiled} without setting any flags.
+         * @param subst the string that substitutes the matched regex, using {@code $} for
+         * group substitution ({@code $1} for 1st group match, {@code $2} for 2nd, etc).
+         */
+        public Builder(@NonNull AutofillId id, @NonNull String regex, @NonNull String subst) {
+            addField(id, regex, subst);
+        }
 
         /**
          * Adds the transformed contents of a field to the overall result of this transformation.
          *
          * @param id id of the screen field.
          * @param regex regular expression with groups (delimited by {@code (} and {@code (}) that
-         * are used to substitute parts of the value.
+         * are used to substitute parts of the value. The pattern will be {@link Pattern#compile
+         * compiled} without setting any flags.
          * @param subst the string that substitutes the matched regex, using {@code $} for
          * group substitution ({@code $1} for 1st group match, {@code $2} for 2nd, etc).
          *
@@ -108,28 +129,23 @@
          */
         public Builder addField(@NonNull AutofillId id, @NonNull String regex,
                 @NonNull String subst) {
-            //TODO(b/62534917): throw exception if regex /subts are invalid
             throwIfDestroyed();
             Preconditions.checkNotNull(id);
             Preconditions.checkNotNull(regex);
             Preconditions.checkNotNull(subst);
-            if (mFields == null) {
-                mFields = new ArrayMap<>();
-            }
-            mFields.put(id, new Pair<>(regex, subst));
+
+            // Check if the regex is valid
+            Pattern pattern = Pattern.compile(regex);
+
+            mFields.put(id, new Pair<>(pattern, subst));
             return this;
         }
 
         /**
          * Creates a new {@link CharSequenceTransformation} instance.
-         *
-         * @throws IllegalStateException if no call to {@link #addField(AutofillId, String, String)}
-         * was made.
          */
         public CharSequenceTransformation build() {
             throwIfDestroyed();
-            Preconditions.checkState(mFields != null && !mFields.isEmpty(),
-                    "Must add at least one field");
             mDestroyed = true;
             return new CharSequenceTransformation(this);
         }
@@ -163,11 +179,11 @@
         final AutofillId[] ids = new AutofillId[size];
         final String[] regexs = new String[size];
         final String[] substs = new String[size];
-        Pair<String, String> pair;
+        Pair<Pattern, String> pair;
         for (int i = 0; i < size; i++) {
             ids[i] = mFields.keyAt(i);
             pair = mFields.valueAt(i);
-            regexs[i] = pair.first;
+            regexs[i] = pair.first.pattern();
             substs[i] = pair.second;
         }
         parcel.writeParcelableArray(ids, flags);
@@ -179,16 +195,18 @@
             new Parcelable.Creator<CharSequenceTransformation>() {
         @Override
         public CharSequenceTransformation createFromParcel(Parcel parcel) {
+            final AutofillId[] ids = parcel.readParcelableArray(null, AutofillId.class);
+            final String[] regexs = parcel.createStringArray();
+            final String[] substs = parcel.createStringArray();
+
             // Always go through the builder to ensure the data ingested by
             // the system obeys the contract of the builder to avoid attacks
             // using specially crafted parcels.
             final CharSequenceTransformation.Builder builder =
-                    new CharSequenceTransformation.Builder();
-            final AutofillId[] ids = parcel.readParcelableArray(null, AutofillId.class);
-            final String[] regexs = parcel.createStringArray();
-            final String[] substs = parcel.createStringArray();
+                    new CharSequenceTransformation.Builder(ids[0], regexs[0], substs[0]);
+
             final int size = ids.length;
-            for (int i = 0; i < size; i++) {
+            for (int i = 1; i < size; i++) {
                 builder.addField(ids[i], regexs[i], substs[i]);
             }
             return builder.build();
diff --git a/core/java/android/service/autofill/ImageTransformation.java b/core/java/android/service/autofill/ImageTransformation.java
index 9f6eedc..5407ad0 100644
--- a/core/java/android/service/autofill/ImageTransformation.java
+++ b/core/java/android/service/autofill/ImageTransformation.java
@@ -18,17 +18,22 @@
 
 import static android.view.autofill.Helper.sDebug;
 
+import android.annotation.DrawableRes;
 import android.annotation.NonNull;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.view.autofill.AutofillId;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
 
 import com.android.internal.util.Preconditions;
 
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
 /**
  * Replaces the content of a child {@link ImageView} of a
  * {@link RemoteViews presentation template} with the first image that matches a regular expression
@@ -37,26 +42,20 @@
  * <p>Typically used to display credit card logos. Example:
  *
  * <pre class="prettyprint">
- *   new ImageTransformation.Builder(ccNumberId)
- *     .addOption("^4815.*$", R.drawable.ic_credit_card_logo1)
+ *   new ImageTransformation.Builder(ccNumberId, "^4815.*$", R.drawable.ic_credit_card_logo1)
  *     .addOption("^1623.*$", R.drawable.ic_credit_card_logo2)
  *     .addOption("^42.*$", R.drawable.ic_credit_card_logo3)
  *     .build();
  * </pre>
  *
  * <p>There is no imposed limit in the number of options, but keep in mind that regexs are
- * expensive to evaluate, so try to:
- * <ul>
- *   <li>Use the minimum number of regex per image.
- *   <li>Add the most common images first.
- * </ul>
+ * expensive to evaluate, so use the minimum number of regexs.
  */
-//TODO(b/62534917): add unit tests
 public final class ImageTransformation extends InternalTransformation implements Parcelable {
     private static final String TAG = "ImageTransformation";
 
     private final AutofillId mId;
-    private final ArrayMap<String, Integer> mOptions;
+    private final ArrayList<Pair<Pattern, Integer>> mOptions;
 
     private ImageTransformation(Builder builder) {
         mId = builder.mId;
@@ -64,6 +63,7 @@
     }
 
     /** @hide */
+    @TestApi
     @Override
     public void apply(@NonNull ValueFinder finder, @NonNull RemoteViews parentTemplate,
             int childViewId) {
@@ -79,10 +79,10 @@
         }
 
         for (int i = 0; i < size; i++) {
-            final String regex = mOptions.keyAt(i);
-            if (value.matches(regex)) {
+            Pair<Pattern, Integer> regex = mOptions.get(i);
+            if (regex.first.matcher(value).matches()) {
                 Log.d(TAG, "Found match at " + i + ": " + regex);
-                parentTemplate.setImageViewResource(childViewId, mOptions.valueAt(i));
+                parentTemplate.setImageViewResource(childViewId, regex.second);
                 return;
             }
         }
@@ -94,19 +94,22 @@
      */
     public static class Builder {
         private final AutofillId mId;
-        private ArrayMap<String, Integer> mOptions;
+        private final ArrayList<Pair<Pattern, Integer>> mOptions = new ArrayList<>();
         private boolean mDestroyed;
 
         /**
-         * Default constructor.
+         * Create a new builder for a autofill id and add a first option.
          *
          * @param id id of the screen field that will be used to evaluate whether the image should
          * be used.
+         * @param regex regular expression defining what should be matched to use this image.
+         * @param resId resource id of the image (in the autofill service's package). The
+         * {@link RemoteViews presentation} must contain a {@link ImageView} child with that id.
          */
-        //TODO(b/62534917): add a regex/resid so we force it to have at least one
-        // (and then remove the check for empty from build())
-        public Builder(@NonNull AutofillId id) {
+        public Builder(@NonNull AutofillId id, @NonNull String regex, @DrawableRes int resId) {
             mId = Preconditions.checkNotNull(id);
+
+            addOption(regex, resId);
         }
 
         /**
@@ -118,13 +121,15 @@
          *
          * @return this build
          */
-        public Builder addOption(String regex, int resId) {
-            //TODO(b/62534917): throw exception if regex / resId are invalid
+        public Builder addOption(@NonNull String regex, @DrawableRes int resId) {
             throwIfDestroyed();
-            if (mOptions == null) {
-                mOptions = new ArrayMap<>();
-            }
-            mOptions.put(regex, resId);
+
+            Preconditions.checkArgument(resId != 0);
+
+            // Check regex
+            Pattern pattern = Pattern.compile(regex);
+
+            mOptions.add(new Pair<>(pattern, resId));
             return this;
         }
 
@@ -163,20 +168,17 @@
     public int describeContents() {
         return 0;
     }
-
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeParcelable(mId, flags);
-        if (mOptions == null) {
-            parcel.writeStringArray(null);
-            return;
-        }
+
         final int size = mOptions.size();
         final String[] regexs = new String[size];
         final int[] resIds = new int[size];
         for (int i = 0; i < size; i++) {
-            regexs[i] = mOptions.keyAt(i);
-            resIds[i] = mOptions.valueAt(i);
+            Pair<Pattern, Integer> regex = mOptions.get(i);
+            regexs[i] = regex.first.pattern();
+            resIds[i] = regex.second;
         }
         parcel.writeStringArray(regexs);
         parcel.writeIntArray(resIds);
@@ -186,19 +188,21 @@
             new Parcelable.Creator<ImageTransformation>() {
         @Override
         public ImageTransformation createFromParcel(Parcel parcel) {
-            // Always go through the builder to ensure the data ingested by
-            // the system obeys the contract of the builder to avoid attacks
-            // using specially crafted parcels.
-            final ImageTransformation.Builder builder =
-                    new ImageTransformation.Builder(parcel.readParcelable(null));
+            final AutofillId id = parcel.readParcelable(null);
+
             final String[] regexs = parcel.createStringArray();
-            if (regexs != null) {
-                final int[] resIds = parcel.createIntArray();
-                final int size = regexs.length;
-                for (int i = 0; i < size; i++) {
-                    builder.addOption(regexs[i], resIds[i]);
-                }
+            final int[] resIds = parcel.createIntArray();
+
+            // Always go through the builder to ensure the data ingested by the system obeys the
+            // contract of the builder to avoid attacks using specially crafted parcels.
+            final ImageTransformation.Builder builder = new ImageTransformation.Builder(id,
+                    regexs[0], resIds[0]);
+
+            final int size = regexs.length;
+            for (int i = 1; i < size; i++) {
+                builder.addOption(regexs[i], resIds[i]);
             }
+
             return builder.build();
         }
 
diff --git a/core/java/android/service/autofill/LuhnChecksumValidator.java b/core/java/android/service/autofill/LuhnChecksumValidator.java
index 713f0f9..f959f3b9 100644
--- a/core/java/android/service/autofill/LuhnChecksumValidator.java
+++ b/core/java/android/service/autofill/LuhnChecksumValidator.java
@@ -19,9 +19,9 @@
 import static android.view.autofill.Helper.sDebug;
 
 import android.annotation.NonNull;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
 import android.util.Log;
 import android.view.autofill.AutofillId;
 
@@ -29,7 +29,7 @@
 
 /**
  * Validator that returns {@code true} if the number created by concatenating all given fields
- * pass a Luhn algorithm checksum.
+ * pass a Luhn algorithm checksum. All non-digits are ignored.
  *
  * <p>See {@link SaveInfo.Builder#setValidator(Validator)} for examples.
  */
@@ -47,8 +47,41 @@
         mIds = Preconditions.checkArrayElementsNotNull(ids, "ids");
     }
 
+    /**
+     * Checks if the Luhn checksum is valid.
+     *
+     * @param number The number including the checksum
+     */
+    private static boolean isLuhnChecksumValid(@NonNull String number) {
+        int sum = 0;
+        boolean isDoubled = false;
+
+        for (int i = number.length() - 1; i >= 0; i--) {
+            final int digit = number.charAt(i) - '0';
+            if (digit < 0 || digit > 9) {
+                // Ignore non-digits
+                continue;
+            }
+
+            int addend;
+            if (isDoubled) {
+                addend = digit * 2;
+                if (addend > 9) {
+                    addend -= 9;
+                }
+            } else {
+                addend = digit;
+            }
+            sum += addend;
+            isDoubled = !isDoubled;
+        }
+
+        return sum % 10 == 0;
+    }
+
     /** @hide */
     @Override
+    @TestApi
     public boolean isValid(@NonNull ValueFinder finder) {
         if (mIds == null || mIds.length == 0) return false;
 
@@ -61,12 +94,8 @@
             }
             number.append(partialNumber);
         }
-        final boolean isValid = TextUtils.isDigitsOnly(number.toString());
-        if (sDebug) Log.d(TAG, "Is valid: " + isValid);
-        // TODO(b/62534917): proper implementation - copy & paste code from:
-        // PaymentUtils.java
-        // PaymentUtilsTest.java
-        return isValid;
+
+        return isLuhnChecksumValid(number.toString());
     }
 
     /////////////////////////////////////
diff --git a/core/java/android/service/autofill/ValueFinder.java b/core/java/android/service/autofill/ValueFinder.java
index d02a358..1705b7d 100644
--- a/core/java/android/service/autofill/ValueFinder.java
+++ b/core/java/android/service/autofill/ValueFinder.java
@@ -17,6 +17,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.view.autofill.AutofillId;
 
 /**
@@ -24,6 +25,7 @@
  *
  * @hide
  */
+@TestApi
 public interface ValueFinder {
 
     /**
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 76c96bd..855c87b 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -16,35 +16,31 @@
 
 package android.service.notification;
 
-import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.TestApi;
-import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
-import android.companion.CompanionDeviceManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-
-import android.annotation.SystemApi;
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.Notification.Builder;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
 import android.app.Service;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
+import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
-import android.graphics.Bitmap;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -54,6 +50,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.widget.RemoteViews;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 
@@ -199,6 +196,7 @@
      * The full trim of the StatusBarNotification including all its features.
      *
      * @hide
+     * @removed
      */
     @SystemApi
     public static final int TRIM_FULL = 0;
@@ -219,6 +217,7 @@
      * </ol>
      *
      * @hide
+     * @removed
      */
     @SystemApi
     public static final int TRIM_LIGHT = 1;
@@ -605,9 +604,9 @@
      * @param snoozeCriterionId The{@link SnoozeCriterion#getId()} of a context to snooze the
      *                          notification until.
      * @hide
+     * @removed
      */
     @SystemApi
-    @TestApi
     public final void snoozeNotification(String key, String snoozeCriterionId) {
         if (!isBound()) return;
         try {
@@ -749,6 +748,7 @@
      * before performing this operation.
      *
      * @hide
+     * @removed
      *
      * @param trim trim of the notifications to be passed via {@link #onNotificationPosted}.
      *             See <code>TRIM_*</code> constants.
@@ -801,6 +801,7 @@
      * current user). Useful when you don't know what's already been posted.
      *
      * @hide
+     * @removed
      *
      * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
      * @return An array of active notifications, sorted in natural order.
@@ -832,6 +833,7 @@
      * more data out of those notifications.
      *
      * @hide
+     * @removed
      *
      * @param keys the keys of the notifications to request
      * @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
@@ -1046,6 +1048,7 @@
      * @param componentName the component that will consume the notification information
      * @param currentUser the user to use as the stream filter
      * @hide
+     * @removed
      */
     @SystemApi
     public void registerAsSystemService(Context context, ComponentName componentName,
@@ -1066,6 +1069,7 @@
      * <p>This method will fail for listeners that were not registered
      * with (@link registerAsService).
      * @hide
+     * @removed
      */
     @SystemApi
     public void unregisterAsSystemService() throws RemoteException {
@@ -1434,9 +1438,9 @@
          * If the {@link NotificationAssistantService} has added people to this notification, then
          * this will be non-null.
          * @hide
+         * @removed
          */
         @SystemApi
-        @TestApi
         public List<String> getAdditionalPeople() {
             return mOverridePeople;
         }
@@ -1446,9 +1450,9 @@
          * user interface displays options for snoozing notifications these criteria should be
          * displayed as well.
          * @hide
+         * @removed
          */
         @SystemApi
-        @TestApi
         public List<SnoozeCriterion> getSnoozeCriteria() {
             return mSnoozeCriteria;
         }
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index ea979c8..05d9167 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -18,6 +18,7 @@
 
 
 import android.annotation.StringRes;
+import android.annotation.TestApi;
 import android.graphics.Rect;
 
 /**
@@ -278,6 +279,7 @@
      * @return true if the UI used to show this action mode can take focus
      * @hide Internal use only
      */
+    @TestApi
     public boolean isUiFocusable() {
         return true;
     }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index b035b7f..a19f05c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -491,10 +491,10 @@
         if (myHeight <= 0) myHeight = getHeight();
 
         final boolean formatChanged = mFormat != mRequestedFormat;
-        final boolean creating = (mSurfaceControl == null || formatChanged)
+        final boolean visibleChanged = mVisible != mRequestedVisible;
+        final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged)
                 && mRequestedVisible;
         final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
-        final boolean visibleChanged = mVisible != mRequestedVisible;
         final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
         boolean redrawNeeded = false;
 
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 13ffeec..7538f65 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -74,6 +74,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.util.Slog;
 import android.view.animation.Animation;
@@ -1311,6 +1312,14 @@
     public boolean isScreenOn();
 
     /**
+     * @return whether the device is currently {@link PowerManager#isInteractive() interactive}.
+     *
+     * Note: the screen can be on while the device is not interactive, e.g. when the device is
+     * showing Ambient Display.
+     */
+    boolean isInteractive();
+
+    /**
      * Tell the policy that the lid switch has changed state.
      * @param whenNanos The time when the change occurred in uptime nanoseconds.
      * @param lidOpen True if the lid is now open.
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 9dd0fb0..eaa4b4b 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -620,7 +620,8 @@
     public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
 
     /**
-     * Represents the event of scrolling a view.
+     * Represents the event of scrolling a view. This event type is generally not sent directly.
+     * @see View#onScrollChanged(int, int, int, int)
      */
     public static final int TYPE_VIEW_SCROLLED = 0x00001000;
 
diff --git a/core/java/android/view/autofill/AutofillId.java b/core/java/android/view/autofill/AutofillId.java
index 1cee529..5ce2421 100644
--- a/core/java/android/view/autofill/AutofillId.java
+++ b/core/java/android/view/autofill/AutofillId.java
@@ -15,6 +15,7 @@
  */
 package android.view.autofill;
 
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.view.View;
@@ -29,6 +30,7 @@
     private final int mVirtualId;
 
     /** @hide */
+    @TestApi
     public AutofillId(int id) {
         mVirtual = false;
         mViewId = id;
diff --git a/core/java/android/webkit/SafeBrowsingResponse.java b/core/java/android/webkit/SafeBrowsingResponse.java
new file mode 100644
index 0000000..dc29d42
--- /dev/null
+++ b/core/java/android/webkit/SafeBrowsingResponse.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 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.webkit;
+
+/**
+ * Used to indicate an action to take when hitting a malicious URL. Instances of this class are
+ * created by the WebView and passed to {@link WebViewClient#onSafebrowsingHit}. The host
+ * application must call {@link #showInterstitial}, {@link #proceed}, or {@link #backToSafety} to
+ * set the WebView's response to the Safe Browsing hit.
+ */
+public abstract class SafeBrowsingResponse {
+
+    /**
+     * Display the default interstitial.
+     *
+     * @param allowReporting True if the interstitial should show a reporting checkbox.
+     */
+    abstract void showInterstitial(boolean allowReporting);
+
+    /**
+     * Act as if the user clicked "visit this unsafe site."
+     *
+     * @param report True to enable Safe Browsing reporting.
+     */
+    abstract void proceed(boolean report);
+
+    /**
+     * Act as if the user clicked "back to safety."
+     *
+     * @param report True to enable Safe Browsing reporting.
+     */
+    abstract void backToSafety(boolean report);
+}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index b490f27..da064d4 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -246,13 +246,6 @@
     /** The resource was blocked because it contains unwanted software */
     public static final int SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE = 3;
 
-    /** Display the default interstitial */
-    public static final int SAFE_BROWSING_ACTION_SHOW_INTERSTITIAL = 0;
-    /** Act as if the user clicked "visit this unsafe site" */
-    public static final int SAFE_BROWSING_ACTION_PROCEED = 1;
-    /** Act as if the user clicked "Back to safety" */
-    public static final int SAFE_BROWSING_ACTION_BACK_TO_SAFETY = 2;
-
     /**
      * Report an error to the host application. These errors are unrecoverable
      * (i.e. the main resource is unavailable). The errorCode parameter
@@ -517,20 +510,19 @@
      * Notify the host application that a loading URL has been flagged by Safe Browsing.
      *
      * The application must invoke the callback to indicate the preferred response. The default
-     * behavior is to show an interstitial to the user (SAFE_BROWSING_ACTION_SHOW_INTERSTITIAL).
+     * behavior is to show an interstitial to the user, with the reporting checkbox visible.
      *
      * If the application needs to show its own custom interstitial UI, the callback can be invoked
-     * asynchronously with SAFE_BROWSING_ACTION_BACK_TO_SAFETY or SAFE_BROWSING_ACTION_PROCEED,
-     * depending on user response.
+     * asynchronously with backToSafety() or proceed(), depending on user response.
      *
      * @param view The WebView that hit the malicious resource.
      * @param request Object containing the details of the request.
      * @param threatType The reason the resource was caught by Safe Browsing, corresponding to a
      *                   SAFE_BROWSING_THREAT_* value.
-     * @param callback Applications must invoke this callback with one of SAFE_BROWSING_ACTION_*.
+     * @param callback Applications must invoke one of the callback methods.
      */
     public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType,
-            ValueCallback<Integer> callback) {
-        callback.onReceiveValue(SAFE_BROWSING_ACTION_SHOW_INTERSTITIAL);
+            SafeBrowsingResponse callback) {
+        callback.showInterstitial(/* allowReporting */ true);
     }
 }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7bdd6da..4d3189e 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -737,6 +737,7 @@
         mInputText.setFilters(new InputFilter[] {
             new InputTextFilter()
         });
+        mInputText.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
 
         mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
         mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
@@ -770,6 +771,12 @@
         if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
         }
+
+        // Should be focusable by default, as the text view whose visibility changes is focusable
+        if (getFocusable() == View.FOCUSABLE_AUTO) {
+            setFocusable(View.FOCUSABLE);
+            setFocusableInTouchMode(true);
+        }
     }
 
     @Override
@@ -856,7 +863,7 @@
         switch (action) {
             case MotionEvent.ACTION_DOWN: {
                 removeAllCallbacks();
-                mInputText.setVisibility(View.INVISIBLE);
+                hideSoftInput();
                 mLastDownOrMoveEventY = mLastDownEventY = event.getY();
                 mLastDownEventTime = event.getEventTime();
                 mIgnoreMoveEvents = false;
@@ -883,11 +890,9 @@
                     mFlingScroller.forceFinished(true);
                     mAdjustScroller.forceFinished(true);
                 } else if (mLastDownEventY < mTopSelectionDividerTop) {
-                    hideSoftInput();
                     postChangeCurrentByOneFromLongPress(
                             false, ViewConfiguration.getLongPressTimeout());
                 } else if (mLastDownEventY > mBottomSelectionDividerBottom) {
-                    hideSoftInput();
                     postChangeCurrentByOneFromLongPress(
                             true, ViewConfiguration.getLongPressTimeout());
                 } else {
@@ -1120,6 +1125,7 @@
     @Override
     public void scrollBy(int x, int y) {
         int[] selectorIndices = mSelectorIndices;
+        int startScrollOffset = mCurrentScrollOffset;
         if (!mWrapSelectorWheel && y > 0
                 && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
             mCurrentScrollOffset = mInitialScrollOffset;
@@ -1147,6 +1153,9 @@
                 mCurrentScrollOffset = mInitialScrollOffset;
             }
         }
+        if (startScrollOffset != mCurrentScrollOffset) {
+            onScrollChanged(0, mCurrentScrollOffset, 0, startScrollOffset);
+        }
     }
 
     @Override
@@ -1281,9 +1290,9 @@
         InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
         if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) {
             inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            if (mHasSelectorWheel) {
-                mInputText.setVisibility(View.INVISIBLE);
-            }
+        }
+        if (mHasSelectorWheel) {
+            mInputText.setVisibility(View.INVISIBLE);
         }
     }
 
@@ -1735,7 +1744,10 @@
         }
         int previous = mValue;
         mValue = current;
-        updateInputTextView();
+        // If we're flinging, we'll update the text view at the end when it becomes visible
+        if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
+            updateInputTextView();
+        }
         if (notifyChange) {
             notifyChange(previous, current);
         }
@@ -1752,7 +1764,7 @@
      */
      private void changeValueByOne(boolean increment) {
         if (mHasSelectorWheel) {
-            mInputText.setVisibility(View.INVISIBLE);
+            hideSoftInput();
             if (!moveToFinalScrollerPosition(mFlingScroller)) {
                 moveToFinalScrollerPosition(mAdjustScroller);
             }
@@ -1799,9 +1811,8 @@
      */
     private void onScrollerFinished(Scroller scroller) {
         if (scroller == mFlingScroller) {
-            if (!ensureScrollWheelAdjusted()) {
-                updateInputTextView();
-            }
+            ensureScrollWheelAdjusted();
+            updateInputTextView();
             onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
         } else {
             if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
@@ -1937,9 +1948,25 @@
          */
         String text = (mDisplayedValues == null) ? formatNumber(mValue)
                 : mDisplayedValues[mValue - mMinValue];
-        if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
-            mInputText.setText(text);
-            return true;
+        if (!TextUtils.isEmpty(text)) {
+            CharSequence beforeText = mInputText.getText();
+            if (!text.equals(beforeText.toString())) {
+                mInputText.setText(text);
+                if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+                    AccessibilityEvent event = AccessibilityEvent.obtain(
+                            AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+                    mInputText.onInitializeAccessibilityEvent(event);
+                    mInputText.onPopulateAccessibilityEvent(event);
+                    event.setFromIndex(0);
+                    event.setRemovedCount(beforeText.length());
+                    event.setAddedCount(text.length());
+                    event.setBeforeText(beforeText);
+                    event.setSource(NumberPicker.this,
+                            AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT);
+                    requestSendAccessibilityEvent(NumberPicker.this, event);
+                }
+                return true;
+            }
         }
 
         return false;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 37961ff..454f5b7 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1578,12 +1578,14 @@
         ViewGroupActionAdd(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info,
                 int depth) {
             viewId = parcel.readInt();
+            mIndex = parcel.readInt();
             mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth);
         }
 
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(VIEW_GROUP_ACTION_ADD_TAG);
             dest.writeInt(viewId);
+            dest.writeInt(mIndex);
             mNestedViews.writeToParcel(dest, flags);
         }
 
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index d61096d..526246b 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -26,6 +26,7 @@
 import android.icu.text.DecimalFormatSymbols;
 import android.os.Parcelable;
 import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.text.style.TtsSpan;
@@ -111,7 +112,11 @@
     private int mCurrentHour;
     private int mCurrentMinute;
     private boolean mIs24Hour;
-    private boolean mIsAmPmAtStart;
+
+    // The portrait layout puts AM/PM at the right by default.
+    private boolean mIsAmPmAtLeft = false;
+    // The landscape layouts put AM/PM at the bottom by default.
+    private boolean mIsAmPmAtTop = false;
 
     // Localization data.
     private boolean mHourFormatShowLeadingZero;
@@ -435,34 +440,70 @@
         if (mIs24Hour) {
             mAmPmLayout.setVisibility(View.GONE);
         } else {
-            // Ensure that AM/PM layout is in the correct position.
+            // Find the location of AM/PM based on locale information.
             final String dateTimePattern = DateFormat.getBestDateTimePattern(mLocale, "hm");
             final boolean isAmPmAtStart = dateTimePattern.startsWith("a");
-            setAmPmAtStart(isAmPmAtStart);
-
+            setAmPmStart(isAmPmAtStart);
             updateAmPmLabelStates(mCurrentHour < 12 ? AM : PM);
         }
     }
 
-    private void setAmPmAtStart(boolean isAmPmAtStart) {
-        if (mIsAmPmAtStart != isAmPmAtStart) {
-            mIsAmPmAtStart = isAmPmAtStart;
-
-            final RelativeLayout.LayoutParams params =
-                    (RelativeLayout.LayoutParams) mAmPmLayout.getLayoutParams();
-            if (params.getRule(RelativeLayout.RIGHT_OF) != 0 ||
-                    params.getRule(RelativeLayout.LEFT_OF) != 0) {
-                if (isAmPmAtStart) {
-                    params.removeRule(RelativeLayout.RIGHT_OF);
-                    params.addRule(RelativeLayout.LEFT_OF, mHourView.getId());
-                } else {
-                    params.removeRule(RelativeLayout.LEFT_OF);
-                    params.addRule(RelativeLayout.RIGHT_OF, mMinuteView.getId());
-                }
+    private void setAmPmStart(boolean isAmPmAtStart) {
+        final RelativeLayout.LayoutParams params =
+                (RelativeLayout.LayoutParams) mAmPmLayout.getLayoutParams();
+        if (params.getRule(RelativeLayout.RIGHT_OF) != 0
+                || params.getRule(RelativeLayout.LEFT_OF) != 0) {
+            // Horizontal mode, with AM/PM appearing to left/right of hours and minutes.
+            final boolean isAmPmAtLeft;
+            if (TextUtils.getLayoutDirectionFromLocale(mLocale) == View.LAYOUT_DIRECTION_LTR) {
+                isAmPmAtLeft = isAmPmAtStart;
+            } else {
+                isAmPmAtLeft = !isAmPmAtStart;
+            }
+            if (mIsAmPmAtLeft == isAmPmAtLeft) {
+                // AM/PM is already at the correct location. No change needed.
+                return;
             }
 
-            mAmPmLayout.setLayoutParams(params);
+            if (isAmPmAtLeft) {
+                params.removeRule(RelativeLayout.RIGHT_OF);
+                params.addRule(RelativeLayout.LEFT_OF, mHourView.getId());
+            } else {
+                params.removeRule(RelativeLayout.LEFT_OF);
+                params.addRule(RelativeLayout.RIGHT_OF, mMinuteView.getId());
+            }
+            mIsAmPmAtLeft = isAmPmAtLeft;
+        } else if (params.getRule(RelativeLayout.BELOW) != 0
+                || params.getRule(RelativeLayout.ABOVE) != 0) {
+            // Vertical mode, with AM/PM appearing to top/bottom of hours and minutes.
+            if (mIsAmPmAtTop == isAmPmAtStart) {
+                // AM/PM is already at the correct location. No change needed.
+                return;
+            }
+
+            final int otherViewId;
+            if (isAmPmAtStart) {
+                otherViewId = params.getRule(RelativeLayout.BELOW);
+                params.removeRule(RelativeLayout.BELOW);
+                params.addRule(RelativeLayout.ABOVE, otherViewId);
+            } else {
+                otherViewId = params.getRule(RelativeLayout.ABOVE);
+                params.removeRule(RelativeLayout.ABOVE);
+                params.addRule(RelativeLayout.BELOW, otherViewId);
+            }
+
+            // Switch the top and bottom paddings on the other view.
+            final View otherView = mRadialTimePickerHeader.findViewById(otherViewId);
+            final int top = otherView.getPaddingTop();
+            final int bottom = otherView.getPaddingBottom();
+            final int left = otherView.getPaddingLeft();
+            final int right = otherView.getPaddingRight();
+            otherView.setPadding(left, bottom, right, top);
+
+            mIsAmPmAtTop = isAmPmAtStart;
         }
+
+        mAmPmLayout.setLayoutParams(params);
     }
 
     /**
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ece4981..54afc95 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -69,7 +69,10 @@
 import android.view.animation.Interpolator;
 import android.widget.AbsListView;
 import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
 import android.widget.ListView;
+import android.widget.Space;
+
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ResolverActivity.TargetInfo;
@@ -1412,6 +1415,10 @@
                 } else {
                     lp.height = v.getMeasuredHeight();
                 }
+                if (i != (mColumnCount - 1)) {
+                    row.addView(new Space(ChooserActivity.this),
+                            new LinearLayout.LayoutParams(0, 0, 1));
+                }
             }
 
             // Pre-measure so we can scale later.
@@ -1439,13 +1446,34 @@
             if (startType == ChooserListAdapter.TARGET_SERVICE) {
                 holder.row.setBackgroundColor(
                         getColor(R.color.chooser_service_row_background_color));
+                int nextStartType = mChooserListAdapter.getPositionTargetType(
+                        getFirstRowPosition(rowPosition + 1));
+                int serviceSpacing = holder.row.getContext().getResources()
+                        .getDimensionPixelSize(R.dimen.chooser_service_spacing);
+                int top = rowPosition == 0 ? serviceSpacing : 0;
+                if (nextStartType != ChooserListAdapter.TARGET_SERVICE) {
+                    setVertPadding(holder, top, serviceSpacing);
+                } else {
+                    setVertPadding(holder, top, 0);
+                }
             } else {
                 holder.row.setBackgroundColor(Color.TRANSPARENT);
+                int lastStartType = mChooserListAdapter.getPositionTargetType(
+                        getFirstRowPosition(rowPosition - 1));
+                if (lastStartType == ChooserListAdapter.TARGET_SERVICE || rowPosition == 0) {
+                    int serviceSpacing = holder.row.getContext().getResources()
+                            .getDimensionPixelSize(R.dimen.chooser_service_spacing);
+                    setVertPadding(holder, serviceSpacing, 0);
+                } else {
+                    setVertPadding(holder, 0, 0);
+                }
             }
 
             final int oldHeight = holder.row.getLayoutParams().height;
+            int measuredRowHeight = holder.measuredRowHeight + holder.row.getPaddingTop()
+                    + holder.row.getPaddingBottom();
             holder.row.getLayoutParams().height = Math.max(1,
-                    (int) (holder.measuredRowHeight * getRowScale(rowPosition)));
+                    (int) (measuredRowHeight * getRowScale(rowPosition)));
             if (holder.row.getLayoutParams().height != oldHeight) {
                 holder.row.requestLayout();
             }
@@ -1457,11 +1485,16 @@
                     holder.itemIndices[i] = start + i;
                     mChooserListAdapter.bindView(holder.itemIndices[i], v);
                 } else {
-                    v.setVisibility(View.GONE);
+                    v.setVisibility(View.INVISIBLE);
                 }
             }
         }
 
+        private void setVertPadding(RowViewHolder holder, int top, int bottom) {
+            holder.row.setPadding(holder.row.getPaddingLeft(), top,
+                    holder.row.getPaddingRight(), bottom);
+        }
+
         int getFirstRowPosition(int row) {
             final int callerCount = mChooserListAdapter.getCallerTargetCount();
             final int callerRows = (int) Math.ceil((float) callerCount / mColumnCount);
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 81ea191..36e4c1c6 100644
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -27,9 +27,6 @@
 
     PackageInfoLite getMinimalPackageInfo(String packagePath, int flags, String abiOverride);
     ObbInfo getObbInfo(String filename);
-    long calculateDirectorySize(String directory);
-    /** Return file system stats: [0] is total bytes, [1] is available bytes */
-    long[] getFileSystemStats(String path);
     void clearDirectory(String directory);
     long calculateInstalledSize(String packagePath, boolean isForwardLocked, String abiOverride);
 }
diff --git a/core/java/com/android/internal/backup/package.html b/core/java/com/android/internal/backup/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/backup/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
similarity index 84%
rename from packages/SystemUI/colorextraction/src/com/google/android/colorextraction/ColorExtractor.java
rename to core/java/com/android/internal/colorextraction/ColorExtractor.java
index 2d794fb..2608698 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -14,19 +14,20 @@
  * limitations under the License
  */
 
-package com.google.android.colorextraction;
+package com.android.internal.colorextraction;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.annotation.VisibleForTesting;
-import android.support.v4.graphics.ColorUtils;
+import android.os.Trace;
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.google.android.colorextraction.types.ExtractionType;
-import com.google.android.colorextraction.types.Tonal;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
 
 import java.util.ArrayList;
 
@@ -50,6 +51,8 @@
     private final ArrayList<OnColorsChangedListener> mOnColorsChangedListeners;
     private final Context mContext;
     private final ExtractionType mExtractionType;
+    private WallpaperColors mSystemColors;
+    private WallpaperColors mLockColors;
 
     public ColorExtractor(Context context) {
         this(context, new Tonal());
@@ -70,7 +73,6 @@
         }
 
         mOnColorsChangedListeners = new ArrayList<>();
-
         WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
         if (wallpaperManager == null) {
             Log.w(TAG, "Can't listen to color changes!");
@@ -78,17 +80,25 @@
             wallpaperManager.addOnColorsChangedListener(this);
 
             // Initialize all gradients with the current colors
-            GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
-            extractInto(wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM),
+            Trace.beginSection("ColorExtractor#getWallpaperColors");
+            mSystemColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+            mLockColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK);
+
+            GradientColors[] systemColors = mGradientColors.get(
+                    WallpaperManager.FLAG_SYSTEM);
+            extractInto(mSystemColors,
                     systemColors[TYPE_NORMAL],
                     systemColors[TYPE_DARK],
                     systemColors[TYPE_EXTRA_DARK]);
 
             GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
-            extractInto(wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK),
+            extractInto(mLockColors,
                     lockColors[TYPE_NORMAL],
                     lockColors[TYPE_DARK],
                     lockColors[TYPE_EXTRA_DARK]);
+            triggerColorsChanged(WallpaperManager.FLAG_SYSTEM
+                    | WallpaperManager.FLAG_LOCK);
+            Trace.endSection();
         }
     }
 
@@ -110,6 +120,7 @@
      * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
      * @return colors
      */
+    @NonNull
     public GradientColors getColors(int which, int type) {
         if (type != TYPE_NORMAL && type != TYPE_DARK && type != TYPE_EXTRA_DARK) {
             throw new IllegalArgumentException(
@@ -121,16 +132,35 @@
         return mGradientColors.get(which)[type];
     }
 
+    /**
+     * Get the last available WallpaperColors without forcing new extraction.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @return Last cached colors
+     */
+    @Nullable
+    public WallpaperColors getWallpaperColors(int which) {
+        if (which == WallpaperManager.FLAG_LOCK) {
+            return mLockColors;
+        } else if (which == WallpaperManager.FLAG_SYSTEM) {
+            return mSystemColors;
+        } else {
+            throw new IllegalArgumentException("Invalid value for which: " + which);
+        }
+    }
+
     @Override
     public void onColorsChanged(WallpaperColors colors, int which) {
         boolean changed = false;
         if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+            mLockColors = colors;
             GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
             extractInto(colors, lockColors[TYPE_NORMAL], lockColors[TYPE_DARK],
                     lockColors[TYPE_EXTRA_DARK]);
             changed = true;
         }
         if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            mSystemColors = colors;
             GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
             extractInto(colors, systemColors[TYPE_NORMAL], systemColors[TYPE_DARK],
                     systemColors[TYPE_EXTRA_DARK]);
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java b/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java
similarity index 95%
rename from packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
rename to core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java
index 2b212c1..500c028 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
+++ b/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java
@@ -14,11 +14,13 @@
  * limitations under the License
  */
 
-package com.google.android.colorextraction.drawable;
+package com.android.internal.colorextraction.drawable;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
@@ -29,13 +31,11 @@
 import android.graphics.Shader;
 import android.graphics.Xfermode;
 import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.v4.graphics.ColorUtils;
 import android.view.animation.DecelerateInterpolator;
 
-import com.google.android.colorextraction.ColorExtractor;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.graphics.ColorUtils;
 
 /**
  * Draws a gradient based on a Palette
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/ExtractionType.java b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
similarity index 93%
rename from packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/ExtractionType.java
rename to core/java/com/android/internal/colorextraction/types/ExtractionType.java
index 4c3ac3e..762b54f 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/ExtractionType.java
+++ b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
@@ -14,11 +14,11 @@
  * limitations under the License
  */
 
-package com.google.android.colorextraction.types;
+package com.android.internal.colorextraction.types;
 
 import android.app.WallpaperColors;
 
-import com.google.android.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor;
 
 /**
  * Interface to allow various color extraction implementations.
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java
similarity index 97%
rename from packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
rename to core/java/com/android/internal/colorextraction/types/Tonal.java
index f59c4a5..b8ebe30 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
+++ b/core/java/com/android/internal/colorextraction/types/Tonal.java
@@ -14,20 +14,19 @@
  * limitations under the License
  */
 
-package com.google.android.colorextraction.types;
+package com.android.internal.colorextraction.types;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.WallpaperColors;
 import android.graphics.Color;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.v4.graphics.ColorUtils;
 import android.util.Log;
 import android.util.MathUtils;
-import android.util.Pair;
 import android.util.Range;
 
-import com.google.android.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.graphics.ColorUtils;
 
 import java.util.Arrays;
 import java.util.List;
@@ -616,7 +615,7 @@
 
     @SuppressWarnings("WeakerAccess")
     @VisibleForTesting
-    static final ColorRange[] BLACKLISTED_COLORS = new ColorRange[] {
+    public static final ColorRange[] BLACKLISTED_COLORS = new ColorRange[] {
 
             // Red
             new ColorRange(
@@ -768,18 +767,18 @@
      * </ul>
      */
     @VisibleForTesting
-    static class ColorRange {
+    public static class ColorRange {
         private Range<Float> mHue;
         private Range<Float> mSaturation;
         private Range<Float> mLightness;
 
-        ColorRange(Range<Float> hue, Range<Float> saturation, Range<Float> lightness) {
+        public ColorRange(Range<Float> hue, Range<Float> saturation, Range<Float> lightness) {
             mHue = hue;
             mSaturation = saturation;
             mLightness = lightness;
         }
 
-        boolean containsColor(float h, float s, float l) {
+        public boolean containsColor(float h, float s, float l) {
             if (!mHue.contains(h)) {
                 return false;
             } else if (!mSaturation.contains(s)) {
@@ -790,8 +789,7 @@
             return true;
         }
 
-        @VisibleForTesting
-        float[] getCenter() {
+        public float[] getCenter() {
             return new float[] {
                     mHue.getLower() + (mHue.getUpper() - mHue.getLower()) / 2f,
                     mSaturation.getLower() + (mSaturation.getUpper() - mSaturation.getLower()) / 2f,
diff --git a/core/java/com/android/internal/inputmethod/package.html b/core/java/com/android/internal/inputmethod/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/logging/package.html b/core/java/com/android/internal/logging/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/logging/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java
new file mode 100644
index 0000000..0c041f2
--- /dev/null
+++ b/core/java/com/android/internal/os/ClassLoaderFactory.java
@@ -0,0 +1,92 @@
+/*
+ * 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.internal.os;
+
+import android.os.Trace;
+
+import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.PathClassLoader;
+
+/**
+ * Creates class loaders.
+ *
+ * @hide
+ */
+public class ClassLoaderFactory {
+    // Unconstructable
+    private ClassLoaderFactory() {}
+
+    private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
+    private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
+            DelegateLastClassLoader.class.getName();
+
+    /**
+     * Returns true if {@code name} is a supported classloader. {@code name} must be a
+     * binary name of a class, as defined by {@code Class.getName}.
+     */
+    public static boolean isValidClassLoaderName(String name) {
+        return PATH_CLASS_LOADER_NAME.equals(name) ||
+                DELEGATE_LAST_CLASS_LOADER_NAME.equals(name);
+    }
+
+    /**
+     * Same as {@code createClassLoader} below, except that no associated namespace
+     * is created.
+     */
+    public static ClassLoader createClassLoader(String dexPath,
+            String librarySearchPath, ClassLoader parent, String classloaderName) {
+        if (classloaderName == null || PATH_CLASS_LOADER_NAME.equals(classloaderName)) {
+            return new PathClassLoader(dexPath, librarySearchPath, parent);
+        } else if (DELEGATE_LAST_CLASS_LOADER_NAME.equals(classloaderName)) {
+            return new DelegateLastClassLoader(dexPath, librarySearchPath, parent);
+        }
+
+        throw new AssertionError("Invalid classLoaderName: " + classloaderName);
+    }
+
+    /**
+     * Create a ClassLoader and initialize a linker-namespace for it.
+     */
+    public static ClassLoader createClassLoader(String dexPath,
+            String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
+            int targetSdkVersion, boolean isNamespaceShared, String classloaderName) {
+
+        final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent,
+                classloaderName);
+
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "createClassloaderNamespace");
+        String errorMessage = createClassloaderNamespace(classLoader,
+                                                         targetSdkVersion,
+                                                         librarySearchPath,
+                                                         libraryPermittedPath,
+                                                         isNamespaceShared);
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+        if (errorMessage != null) {
+            throw new UnsatisfiedLinkError("Unable to create namespace for the classloader " +
+                                           classLoader + ": " + errorMessage);
+        }
+
+        return classLoader;
+    }
+
+    private static native String createClassloaderNamespace(ClassLoader classLoader,
+                                                            int targetSdkVersion,
+                                                            String librarySearchPath,
+                                                            String libraryPermittedPath,
+                                                            boolean isNamespaceShared);
+}
diff --git a/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java b/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java
index aa56e93..15a5e3e 100644
--- a/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java
+++ b/core/java/com/android/internal/os/KernelMemoryBandwidthStats.java
@@ -1,6 +1,7 @@
 package com.android.internal.os;
 
 import android.os.StrictMode;
+import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.LongSparseLongArray;
 import android.util.Slog;
@@ -37,6 +38,8 @@
             return;
         }
 
+        final long startTime = SystemClock.uptimeMillis();
+
         StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
         try (BufferedReader reader = new BufferedReader(new FileReader(mSysfsFile))) {
             parseStats(reader);
@@ -50,6 +53,11 @@
         } finally {
             StrictMode.setThreadPolicy(policy);
         }
+
+        final long readTime = SystemClock.uptimeMillis() - startTime;
+        if (DEBUG || readTime > 100) {
+            Slog.w(TAG, "Reading memory bandwidth file took " + readTime + "ms");
+        }
     }
 
     @VisibleForTesting
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 8036f257..7178ec7 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -16,6 +16,7 @@
 package com.android.internal.os;
 
 import android.os.Process;
+import android.os.SystemClock;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -66,6 +67,7 @@
         byte[] buffer = new byte[32*1024];
         int len;
         boolean wakeup_sources;
+        final long startTime = SystemClock.uptimeMillis();
 
         try {
             FileInputStream is;
@@ -90,6 +92,11 @@
             return null;
         }
 
+        final long readTime = SystemClock.uptimeMillis() - startTime;
+        if (readTime > 100) {
+            Slog.w(TAG, "Reading wakelock stats took " + readTime + "ms");
+        }
+
         if (len > 0) {
             if (len >= buffer.length) {
                 Slog.wtf(TAG, "Kernel wake locks exceeded buffer size " + buffer.length);
diff --git a/core/java/com/android/internal/os/PathClassLoaderFactory.java b/core/java/com/android/internal/os/PathClassLoaderFactory.java
deleted file mode 100644
index 06a93b2..0000000
--- a/core/java/com/android/internal/os/PathClassLoaderFactory.java
+++ /dev/null
@@ -1,66 +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.internal.os;
-
-import android.os.Trace;
-
-import dalvik.system.PathClassLoader;
-
-/**
- * Creates path class loaders.
- *
- * @hide
- */
-public class PathClassLoaderFactory {
-    // Unconstructable
-    private PathClassLoaderFactory() {}
-
-    /**
-     * Create a PathClassLoader and initialize a linker-namespace for it.
-     *
-     * @hide
-     */
-    public static PathClassLoader createClassLoader(String dexPath,
-                                                    String librarySearchPath,
-                                                    String libraryPermittedPath,
-                                                    ClassLoader parent,
-                                                    int targetSdkVersion,
-                                                    boolean isNamespaceShared) {
-        PathClassLoader pathClassloader = new PathClassLoader(dexPath, librarySearchPath, parent);
-
-        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "createClassloaderNamespace");
-        String errorMessage = createClassloaderNamespace(pathClassloader,
-                                                         targetSdkVersion,
-                                                         librarySearchPath,
-                                                         libraryPermittedPath,
-                                                         isNamespaceShared);
-        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-
-        if (errorMessage != null) {
-            throw new UnsatisfiedLinkError("Unable to create namespace for the classloader " +
-                                           pathClassloader + ": " + errorMessage);
-        }
-
-        return pathClassloader;
-    }
-
-    private static native String createClassloaderNamespace(ClassLoader classLoader,
-                                                            int targetSdkVersion,
-                                                            String librarySearchPath,
-                                                            String libraryPermittedPath,
-                                                            boolean isNamespaceShared);
-}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index f4be128..66475e4 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -31,6 +31,7 @@
 import com.android.internal.logging.AndroidConfig;
 import com.android.server.NetworkManagementSocketTagger;
 import dalvik.system.VMRuntime;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.TimeZone;
@@ -228,8 +229,8 @@
      * @param argv Argument vector for main()
      * @param classLoader the classLoader to load {@className} with
      */
-    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
-            throws Zygote.MethodAndArgsCaller {
+    private static Runnable findStaticMain(String className, String[] argv,
+            ClassLoader classLoader) {
         Class<?> cl;
 
         try {
@@ -263,7 +264,7 @@
          * clears up all the stack frames that were required in setting
          * up the process.
          */
-        throw new Zygote.MethodAndArgsCaller(m, argv);
+        return new MethodAndArgsCaller(m, argv);
     }
 
     public static final void main(String[] argv) {
@@ -286,8 +287,8 @@
         if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
     }
 
-    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
-            throws Zygote.MethodAndArgsCaller {
+    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
+            ClassLoader classLoader) {
         // If the application calls System.exit(), terminate the process
         // immediately without running any shutdown hooks.  It is not possible to
         // shutdown an Android application gracefully.  Among other things, the
@@ -300,20 +301,13 @@
         VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
         VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
 
-        final Arguments args;
-        try {
-            args = new Arguments(argv);
-        } catch (IllegalArgumentException ex) {
-            Slog.e(TAG, ex.getMessage());
-            // let the process exit
-            return;
-        }
+        final Arguments args = new Arguments(argv);
 
         // The end of of the RuntimeInit event (see #zygoteInit).
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
         // Remaining arguments are passed to the start class's static main
-        invokeStaticMain(args.startClass, args.startArgs, classLoader);
+        return findStaticMain(args.startClass, args.startArgs, classLoader);
     }
 
     /**
@@ -422,4 +416,37 @@
             System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
         }
     }
+
+    /**
+     * Helper class which holds a method and arguments and can call them. This is used as part of
+     * a trampoline to get rid of the initial process setup stack frames.
+     */
+    static class MethodAndArgsCaller implements Runnable {
+        /** method to call */
+        private final Method mMethod;
+
+        /** argument array */
+        private final String[] mArgs;
+
+        public MethodAndArgsCaller(Method method, String[] args) {
+            mMethod = method;
+            mArgs = args;
+        }
+
+        public void run() {
+            try {
+                mMethod.invoke(null, new Object[] { mArgs });
+            } catch (IllegalAccessException ex) {
+                throw new RuntimeException(ex);
+            } catch (InvocationTargetException ex) {
+                Throwable cause = ex.getCause();
+                if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                } else if (cause instanceof Error) {
+                    throw (Error) cause;
+                }
+                throw new RuntimeException(ex);
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index 58e4a3e..cadb66a 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -29,7 +29,7 @@
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 
 /**
  * Startup class for the WebView zygote process.
@@ -69,8 +69,7 @@
         }
 
         @Override
-        protected boolean handlePreloadPackage(String packagePath, String libsPath,
-                                               String cacheKey) {
+        protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
             Log.i(TAG, "Beginning package preload");
             // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
             // our children will reuse the same classloader instead of creating their own.
@@ -92,13 +91,18 @@
             try {
                 Class<WebViewFactoryProvider> providerClass =
                         WebViewFactory.getWebViewProviderClass(loader);
-                Object result = providerClass.getMethod("preloadInZygote").invoke(null);
-                preloadSucceeded = ((Boolean) result).booleanValue();
-                if (!preloadSucceeded) {
-                    Log.e(TAG, "preloadInZygote returned false");
+                Method preloadInZygote = providerClass.getMethod("preloadInZygote");
+                preloadInZygote.setAccessible(true);
+                if (preloadInZygote.getReturnType() != Boolean.TYPE) {
+                    Log.e(TAG, "Unexpected return type: preloadInZygote must return boolean");
+                } else {
+                    preloadSucceeded = (boolean) providerClass.getMethod("preloadInZygote")
+                            .invoke(null);
+                    if (!preloadSucceeded) {
+                        Log.e(TAG, "preloadInZygote returned false");
+                    }
                 }
-            } catch (ClassNotFoundException | NoSuchMethodException | SecurityException |
-                     IllegalAccessException | InvocationTargetException e) {
+            } catch (ReflectiveOperationException e) {
                 Log.e(TAG, "Exception while preloading package", e);
             }
 
@@ -106,12 +110,10 @@
                 DataOutputStream socketOut = getSocketOutputStream();
                 socketOut.writeInt(preloadSucceeded ? 1 : 0);
             } catch (IOException ioe) {
-                Log.e(TAG, "Error writing to command socket", ioe);
-                return true;
+                throw new IllegalStateException("Error writing to command socket", ioe);
             }
 
             Log.i(TAG, "Package preload done");
-            return false;
         }
     }
 
@@ -125,16 +127,23 @@
             throw new RuntimeException("Failed to setpgid(0,0)", ex);
         }
 
+        final Runnable caller;
         try {
             sServer.registerServerSocket("webview_zygote");
-            sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
-            sServer.closeServerSocket();
-        } catch (Zygote.MethodAndArgsCaller caller) {
-            caller.run();
+            // The select loop returns early in the child process after a fork and
+            // loops forever in the zygote.
+            caller = sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
         } catch (RuntimeException e) {
             Log.e(TAG, "Fatal exception:", e);
+            throw e;
+        } finally {
+            sServer.closeServerSocket();
         }
 
-        System.exit(0);
+        // We're in the child process and have exited the select loop. Proceed to execute the
+        // command.
+        if (caller != null) {
+            caller.run();
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index 608bc9f..89328b2 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -25,7 +25,6 @@
 import android.system.StructCapUserHeader;
 import android.util.BootTimingsTraceLog;
 import android.util.Slog;
-import com.android.internal.os.Zygote.MethodAndArgsCaller;
 import dalvik.system.VMRuntime;
 import java.io.DataOutputStream;
 import java.io.FileDescriptor;
@@ -61,37 +60,35 @@
      * @param args The command-line arguments.
      */
     public static void main(String[] args) {
-        try {
-            // Parse our mandatory arguments.
-            int fdNum = Integer.parseInt(args[0], 10);
-            int targetSdkVersion = Integer.parseInt(args[1], 10);
+        // Parse our mandatory arguments.
+        int fdNum = Integer.parseInt(args[0], 10);
+        int targetSdkVersion = Integer.parseInt(args[1], 10);
 
-            // Tell the Zygote what our actual PID is (since it only knows about the
-            // wrapper that it directly forked).
-            if (fdNum != 0) {
-                try {
-                    FileDescriptor fd = new FileDescriptor();
-                    fd.setInt$(fdNum);
-                    DataOutputStream os = new DataOutputStream(new FileOutputStream(fd));
-                    os.writeInt(Process.myPid());
-                    os.close();
-                    IoUtils.closeQuietly(fd);
-                } catch (IOException ex) {
-                    Slog.d(TAG, "Could not write pid of wrapped process to Zygote pipe.", ex);
-                }
+        // Tell the Zygote what our actual PID is (since it only knows about the
+        // wrapper that it directly forked).
+        if (fdNum != 0) {
+            try {
+                FileDescriptor fd = new FileDescriptor();
+                fd.setInt$(fdNum);
+                DataOutputStream os = new DataOutputStream(new FileOutputStream(fd));
+                os.writeInt(Process.myPid());
+                os.close();
+                IoUtils.closeQuietly(fd);
+            } catch (IOException ex) {
+                Slog.d(TAG, "Could not write pid of wrapped process to Zygote pipe.", ex);
             }
-
-            // Mimic system Zygote preloading.
-            ZygoteInit.preload(new BootTimingsTraceLog("WrapperInitTiming",
-                    Trace.TRACE_TAG_DALVIK));
-
-            // Launch the application.
-            String[] runtimeArgs = new String[args.length - 2];
-            System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
-            WrapperInit.wrapperInit(targetSdkVersion, runtimeArgs);
-        } catch (Zygote.MethodAndArgsCaller caller) {
-            caller.run();
         }
+
+        // Mimic system Zygote preloading.
+        ZygoteInit.preload(new BootTimingsTraceLog("WrapperInitTiming",
+                Trace.TRACE_TAG_DALVIK));
+
+        // Launch the application.
+        String[] runtimeArgs = new String[args.length - 2];
+        System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
+        Runnable r = wrapperInit(targetSdkVersion, runtimeArgs);
+
+        r.run();
     }
 
     /**
@@ -142,8 +139,7 @@
      * @param targetSdkVersion target SDK version
      * @param argv arg strings
      */
-    private static void wrapperInit(int targetSdkVersion, String[] argv)
-            throws Zygote.MethodAndArgsCaller {
+    private static Runnable wrapperInit(int targetSdkVersion, String[] argv) {
         if (RuntimeInit.DEBUG) {
             Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from wrapper");
         }
@@ -165,7 +161,7 @@
 
         // Perform the same initialization that would happen after the Zygote forks.
         Zygote.nativePreApplicationInit();
-        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
+        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
     }
 
     /**
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 0106b81..a9350db 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -221,39 +221,4 @@
             command.append(" '").append(arg.replace("'", "'\\''")).append("'");
         }
     }
-
-    /**
-     * Helper exception class which holds a method and arguments and
-     * can call them. This is used as part of a trampoline to get rid of
-     * the initial process setup stack frames.
-     */
-    public static class MethodAndArgsCaller extends Exception
-            implements Runnable {
-        /** method to call */
-        private final Method mMethod;
-
-        /** argument array */
-        private final String[] mArgs;
-
-        public MethodAndArgsCaller(Method method, String[] args) {
-            mMethod = method;
-            mArgs = args;
-        }
-
-        public void run() {
-            try {
-                mMethod.invoke(null, new Object[] { mArgs });
-            } catch (IllegalAccessException ex) {
-                throw new RuntimeException(ex);
-            } catch (InvocationTargetException ex) {
-                Throwable cause = ex.getCause();
-                if (cause instanceof RuntimeException) {
-                    throw (RuntimeException) cause;
-                } else if (cause instanceof Error) {
-                    throw (Error) cause;
-                }
-                throw new RuntimeException(ex);
-            }
-        }
-    }
 }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index f0c0b99..33382ed 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -26,7 +26,6 @@
 import android.net.LocalSocket;
 import android.os.FactoryTest;
 import android.os.Process;
-import android.os.SELinux;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.system.ErrnoException;
@@ -36,15 +35,13 @@
 import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.EOFException;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.PrintStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Arrays;
 import libcore.io.IoUtils;
 
 /**
@@ -80,6 +77,7 @@
     private final BufferedReader mSocketReader;
     private final Credentials peer;
     private final String abiList;
+    private boolean isEof;
 
     /**
      * Constructs instance from connected socket.
@@ -106,6 +104,8 @@
             Log.e(TAG, "Cannot read peer credentials", ex);
             throw ex;
         }
+
+        isEof = false;
     }
 
     /**
@@ -118,21 +118,14 @@
     }
 
     /**
-     * Reads one start command from the command socket. If successful,
-     * a child is forked and a {@link Zygote.MethodAndArgsCaller}
-     * exception is thrown in that child while in the parent process,
-     * the method returns normally. On failure, the child is not
-     * spawned and messages are printed to the log and stderr. Returns
-     * a boolean status value indicating whether an end-of-file on the command
-     * socket has been encountered.
+     * Reads one start command from the command socket. If successful, a child is forked and a
+     * {@code Runnable} that calls the childs main method (or equivalent) is returned in the child
+     * process. {@code null} is always returned in the parent process (the zygote).
      *
-     * @return false if command socket should continue to be read from, or
-     * true if an end-of-file has been encountered.
-     * @throws Zygote.MethodAndArgsCaller trampoline to invoke main()
-     * method in child process
+     * If the client closes the socket, an {@code EOF} condition is set, which callers can test
+     * for by calling {@code ZygoteConnection.isClosedByPeer}.
      */
-    boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
-
+    Runnable processOneCommand(ZygoteServer zygoteServer) {
         String args[];
         Arguments parsedArgs = null;
         FileDescriptor[] descriptors;
@@ -141,130 +134,120 @@
             args = readArgumentList();
             descriptors = mSocket.getAncillaryFileDescriptors();
         } catch (IOException ex) {
-            Log.w(TAG, "IOException on command socket " + ex.getMessage());
-            closeSocket();
-            return true;
+            throw new IllegalStateException("IOException on command socket", ex);
         }
 
+        // readArgumentList returns null only when it has reached EOF with no available
+        // data to read. This will only happen when the remote socket has disconnected.
         if (args == null) {
-            // EOF reached.
-            closeSocket();
-            return true;
-        }
-
-        /** the stderr of the most recent request, if avail */
-        PrintStream newStderr = null;
-
-        if (descriptors != null && descriptors.length >= 3) {
-            newStderr = new PrintStream(
-                    new FileOutputStream(descriptors[2]));
+            isEof = true;
+            return null;
         }
 
         int pid = -1;
         FileDescriptor childPipeFd = null;
         FileDescriptor serverPipeFd = null;
 
-        try {
-            parsedArgs = new Arguments(args);
+        parsedArgs = new Arguments(args);
 
-            if (parsedArgs.abiListQuery) {
-                return handleAbiListQuery();
-            }
+        if (parsedArgs.abiListQuery) {
+            handleAbiListQuery();
+            return null;
+        }
 
-            if (parsedArgs.preloadDefault) {
-                return handlePreload();
-            }
+        if (parsedArgs.preloadDefault) {
+            handlePreload();
+            return null;
+        }
 
-            if (parsedArgs.preloadPackage != null) {
-                return handlePreloadPackage(parsedArgs.preloadPackage,
-                        parsedArgs.preloadPackageLibs, parsedArgs.preloadPackageCacheKey);
-            }
+        if (parsedArgs.preloadPackage != null) {
+            handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
+                    parsedArgs.preloadPackageCacheKey);
+            return null;
+        }
 
-            if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
-                throw new ZygoteSecurityException("Client may not specify capabilities: " +
-                        "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
-                        ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
-            }
+        if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
+            throw new ZygoteSecurityException("Client may not specify capabilities: " +
+                    "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
+                    ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
+        }
 
-            applyUidSecurityPolicy(parsedArgs, peer);
-            applyInvokeWithSecurityPolicy(parsedArgs, peer);
+        applyUidSecurityPolicy(parsedArgs, peer);
+        applyInvokeWithSecurityPolicy(parsedArgs, peer);
 
-            applyDebuggerSystemProperty(parsedArgs);
-            applyInvokeWithSystemProperty(parsedArgs);
+        applyDebuggerSystemProperty(parsedArgs);
+        applyInvokeWithSystemProperty(parsedArgs);
 
-            int[][] rlimits = null;
+        int[][] rlimits = null;
 
-            if (parsedArgs.rlimits != null) {
-                rlimits = parsedArgs.rlimits.toArray(intArray2d);
-            }
+        if (parsedArgs.rlimits != null) {
+            rlimits = parsedArgs.rlimits.toArray(intArray2d);
+        }
 
-            int[] fdsToIgnore = null;
+        int[] fdsToIgnore = null;
 
-            if (parsedArgs.invokeWith != null) {
+        if (parsedArgs.invokeWith != null) {
+            try {
                 FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                 childPipeFd = pipeFds[1];
                 serverPipeFd = pipeFds[0];
                 Os.fcntlInt(childPipeFd, F_SETFD, 0);
-                fdsToIgnore = new int[] { childPipeFd.getInt$(), serverPipeFd.getInt$() };
+                fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
+            } catch (ErrnoException errnoEx) {
+                throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
             }
-
-            /**
-             * In order to avoid leaking descriptors to the Zygote child,
-             * the native code must close the two Zygote socket descriptors
-             * in the child process before it switches from Zygote-root to
-             * the UID and privileges of the application being launched.
-             *
-             * In order to avoid "bad file descriptor" errors when the
-             * two LocalSocket objects are closed, the Posix file
-             * descriptors are released via a dup2() call which closes
-             * the socket and substitutes an open descriptor to /dev/null.
-             */
-
-            int [] fdsToClose = { -1, -1 };
-
-            FileDescriptor fd = mSocket.getFileDescriptor();
-
-            if (fd != null) {
-                fdsToClose[0] = fd.getInt$();
-            }
-
-            fd = zygoteServer.getServerSocketFileDescriptor();
-
-            if (fd != null) {
-                fdsToClose[1] = fd.getInt$();
-            }
-
-            fd = null;
-
-            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
-                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
-                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
-                    parsedArgs.appDataDir);
-        } catch (ErrnoException ex) {
-            logAndPrintError(newStderr, "Exception creating pipe", ex);
-        } catch (IllegalArgumentException ex) {
-            logAndPrintError(newStderr, "Invalid zygote arguments", ex);
-        } catch (ZygoteSecurityException ex) {
-            logAndPrintError(newStderr,
-                    "Zygote security policy prevents request: ", ex);
         }
 
+        /**
+         * In order to avoid leaking descriptors to the Zygote child,
+         * the native code must close the two Zygote socket descriptors
+         * in the child process before it switches from Zygote-root to
+         * the UID and privileges of the application being launched.
+         *
+         * In order to avoid "bad file descriptor" errors when the
+         * two LocalSocket objects are closed, the Posix file
+         * descriptors are released via a dup2() call which closes
+         * the socket and substitutes an open descriptor to /dev/null.
+         */
+
+        int [] fdsToClose = { -1, -1 };
+
+        FileDescriptor fd = mSocket.getFileDescriptor();
+
+        if (fd != null) {
+            fdsToClose[0] = fd.getInt$();
+        }
+
+        fd = zygoteServer.getServerSocketFileDescriptor();
+
+        if (fd != null) {
+            fdsToClose[1] = fd.getInt$();
+        }
+
+        fd = null;
+
+        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
+                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
+                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
+                parsedArgs.appDataDir);
+
         try {
             if (pid == 0) {
                 // in child
+                zygoteServer.setForkChild();
+
                 zygoteServer.closeServerSocket();
                 IoUtils.closeQuietly(serverPipeFd);
                 serverPipeFd = null;
-                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
 
-                // should never get here, the child is expected to either
-                // throw Zygote.MethodAndArgsCaller or exec().
-                return true;
+                return handleChildProc(parsedArgs, descriptors, childPipeFd);
             } else {
-                // in parent...pid of < 0 means failure
+                // In the parent. A pid < 0 indicates a failure and will be handled in
+                // handleParentProc.
                 IoUtils.closeQuietly(childPipeFd);
                 childPipeFd = null;
-                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
+                handleParentProc(pid, descriptors, serverPipeFd);
+                return null;
             }
         } finally {
             IoUtils.closeQuietly(childPipeFd);
@@ -272,15 +255,13 @@
         }
     }
 
-    private boolean handleAbiListQuery() {
+    private void handleAbiListQuery() {
         try {
             final byte[] abiListBytes = abiList.getBytes(StandardCharsets.US_ASCII);
             mSocketOutStream.writeInt(abiListBytes.length);
             mSocketOutStream.write(abiListBytes);
-            return false;
         } catch (IOException ioe) {
-            Log.e(TAG, "Error writing to command socket", ioe);
-            return true;
+            throw new IllegalStateException("Error writing to command socket", ioe);
         }
     }
 
@@ -290,7 +271,7 @@
      * if no preload was initiated. The latter implies that the zygote is not configured to load
      * resources lazy or that the zygote has already handled a previous request to handlePreload.
      */
-    private boolean handlePreload() {
+    private void handlePreload() {
         try {
             if (isPreloadComplete()) {
                 mSocketOutStream.writeInt(1);
@@ -298,11 +279,8 @@
                 preload();
                 mSocketOutStream.writeInt(0);
             }
-
-            return false;
         } catch (IOException ioe) {
-            Log.e(TAG, "Error writing to command socket", ioe);
-            return true;
+            throw new IllegalStateException("Error writing to command socket", ioe);
         }
     }
 
@@ -318,7 +296,7 @@
         return mSocketOutStream;
     }
 
-    protected boolean handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
+    protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
         throw new RuntimeException("Zyogte does not support package preloading");
     }
 
@@ -334,6 +312,10 @@
         }
     }
 
+    boolean isClosedByPeer() {
+        return isEof;
+    }
+
     /**
      * Handles argument parsing for args related to the zygote spawner.
      *
@@ -781,15 +763,9 @@
      * @param parsedArgs non-null; zygote args
      * @param descriptors null-ok; new file descriptors for stdio if available.
      * @param pipeFd null-ok; pipe for communication back to Zygote.
-     * @param newStderr null-ok; stream to use for stderr until stdio
-     * is reopened.
-     *
-     * @throws Zygote.MethodAndArgsCaller on success to
-     * trampoline to code that invokes static main.
      */
-    private void handleChildProc(Arguments parsedArgs,
-            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
-            throws Zygote.MethodAndArgsCaller {
+    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
+            FileDescriptor pipeFd) {
         /**
          * By the time we get here, the native code has closed the two actual Zygote
          * socket connections, and substituted /dev/null in their place.  The LocalSocket
@@ -806,7 +782,6 @@
                 for (FileDescriptor fd: descriptors) {
                     IoUtils.closeQuietly(fd);
                 }
-                newStderr = System.err;
             } catch (ErrnoException ex) {
                 Log.e(TAG, "Error reopening stdio", ex);
             }
@@ -823,9 +798,12 @@
                     parsedArgs.niceName, parsedArgs.targetSdkVersion,
                     VMRuntime.getCurrentInstructionSet(),
                     pipeFd, parsedArgs.remainingArgs);
+
+            // Should not get here.
+            throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
         } else {
-            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
-                    parsedArgs.remainingArgs, null /* classLoader */);
+            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
+                    null /* classLoader */);
         }
     }
 
@@ -837,13 +815,8 @@
      * @param descriptors null-ok; file descriptors for child's new stdio if
      * specified.
      * @param pipeFd null-ok; pipe for communication with child.
-     * @param parsedArgs non-null; zygote args
-     * @return true for "exit command loop" and false for "continue command
-     * loop"
      */
-    private boolean handleParentProc(int pid,
-            FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {
-
+    private void handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd) {
         if (pid > 0) {
             setChildPgid(pid);
         }
@@ -892,11 +865,8 @@
             mSocketOutStream.writeInt(pid);
             mSocketOutStream.writeBoolean(usingWrapper);
         } catch (IOException ex) {
-            Log.e(TAG, "Error writing to command socket", ex);
-            return true;
+            throw new IllegalStateException("Error writing to command socket", ex);
         }
-
-        return false;
     }
 
     private void setChildPgid(int pid) {
@@ -912,20 +882,4 @@
                 + "normal if peer is not in our session");
         }
     }
-
-    /**
-     * Logs an error message and prints it to the specified stream, if
-     * provided
-     *
-     * @param newStderr null-ok; a standard error stream
-     * @param message non-null; error message
-     * @param ex null-ok an exception
-     */
-    private static void logAndPrintError (PrintStream newStderr,
-            String message, Throwable ex) {
-        Log.e(TAG, message, ex);
-        if (newStderr != null) {
-            newStderr.println(message + (ex == null ? "" : ex));
-        }
-    }
 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 385976c..07edc72 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -24,7 +24,6 @@
 import android.icu.impl.CacheValue;
 import android.icu.text.DecimalFormatSymbols;
 import android.icu.util.ULocale;
-import android.net.LocalServerSocket;
 import android.opengl.EGL14;
 import android.os.Build;
 import android.os.IInstalld;
@@ -132,6 +131,9 @@
         bootTimingsTraceLog.traceBegin("PreloadResources");
         preloadResources();
         bootTimingsTraceLog.traceEnd(); // PreloadResources
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
+        nativePreloadAppProcessHALs();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
         Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
         preloadOpenGL();
         Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
@@ -184,6 +186,8 @@
         System.loadLibrary("jnigraphics");
     }
 
+    native private static void nativePreloadAppProcessHALs();
+
     private static void preloadOpenGL() {
         String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
         if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
@@ -446,10 +450,7 @@
     /**
      * Finish remaining work for the newly forked system server process.
      */
-    private static void handleSystemServerProcess(
-            ZygoteConnection.Arguments parsedArgs)
-            throws Zygote.MethodAndArgsCaller {
-
+    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
         // set umask to 0077 so new files and directories will default to owner-only permissions.
         Os.umask(S_IRWXG | S_IRWXO);
 
@@ -495,6 +496,8 @@
             WrapperInit.execApplication(parsedArgs.invokeWith,
                     parsedArgs.niceName, parsedArgs.targetSdkVersion,
                     VMRuntime.getCurrentInstructionSet(), null, args);
+
+            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
         } else {
             ClassLoader cl = null;
             if (systemServerClasspath != null) {
@@ -506,7 +509,7 @@
             /*
              * Pass the remaining arguments to SystemServer.
              */
-            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
+            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
         }
 
         /* should never reach here */
@@ -517,15 +520,12 @@
      * namespace, i.e., this classloader can access platform-private native libraries. The
      * classloader will use java.library.path as the native library path.
      */
-    static PathClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
-      String libraryPath = System.getProperty("java.library.path");
+    static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
+        String libraryPath = System.getProperty("java.library.path");
 
-      return PathClassLoaderFactory.createClassLoader(classPath,
-                                                      libraryPath,
-                                                      libraryPath,
-                                                      ClassLoader.getSystemClassLoader(),
-                                                      targetSdkVersion,
-                                                      true /* isNamespaceShared */);
+        return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
+                ClassLoader.getSystemClassLoader(), targetSdkVersion, true /* isNamespaceShared */,
+                null /* classLoaderName */);
     }
 
     /**
@@ -588,10 +588,13 @@
     }
 
     /**
-     * Prepare the arguments and fork for the system server process.
+     * Prepare the arguments and forks for the system server process.
+     *
+     * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
+     * child process, and {@code null} in the parent.
      */
-    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
-            throws Zygote.MethodAndArgsCaller, RuntimeException {
+    private static Runnable forkSystemServer(String abiList, String socketName,
+            ZygoteServer zygoteServer) {
         long capabilities = posixCapabilitiesAsBits(
             OsConstants.CAP_IPC_LOCK,
             OsConstants.CAP_KILL,
@@ -648,10 +651,10 @@
             }
 
             zygoteServer.closeServerSocket();
-            handleSystemServerProcess(parsedArgs);
+            return handleSystemServerProcess(parsedArgs);
         }
 
-        return true;
+        return null;
     }
 
     /**
@@ -682,6 +685,7 @@
             throw new RuntimeException("Failed to setpgid(0,0)", ex);
         }
 
+        final Runnable caller;
         try {
             // Report Zygote start time to tron unless it is a runtime restart
             if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
@@ -751,19 +755,32 @@
             ZygoteHooks.stopZygoteNoThreadCreation();
 
             if (startSystemServer) {
-                startSystemServer(abiList, socketName, zygoteServer);
+                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
+
+                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
+                // child (system_server) process.
+                if (r != null) {
+                    r.run();
+                    return;
+                }
             }
 
             Log.i(TAG, "Accepting command socket connections");
-            zygoteServer.runSelectLoop(abiList);
 
-            zygoteServer.closeServerSocket();
-        } catch (Zygote.MethodAndArgsCaller caller) {
-            caller.run();
+            // The select loop returns early in the child process after a fork and
+            // loops forever in the zygote.
+            caller = zygoteServer.runSelectLoop(abiList);
         } catch (Throwable ex) {
             Log.e(TAG, "System zygote died with exception", ex);
-            zygoteServer.closeServerSocket();
             throw ex;
+        } finally {
+            zygoteServer.closeServerSocket();
+        }
+
+        // We're in the child process and have exited the select loop. Proceed to execute the
+        // command.
+        if (caller != null) {
+            caller.run();
         }
     }
 
@@ -807,8 +824,7 @@
      * @param targetSdkVersion target SDK version
      * @param argv arg strings
      */
-    public static final void zygoteInit(int targetSdkVersion, String[] argv,
-            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
+    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
         if (RuntimeInit.DEBUG) {
             Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
         }
@@ -818,7 +834,7 @@
 
         RuntimeInit.commonInit();
         ZygoteInit.nativeZygoteInit();
-        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
+        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
     }
 
     private static final native void nativeZygoteInit();
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index 126d9e7..8baa15a 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -25,6 +25,7 @@
 import android.system.StructPollfd;
 import android.util.Log;
 
+import android.util.Slog;
 import java.io.IOException;
 import java.io.FileDescriptor;
 import java.util.ArrayList;
@@ -45,9 +46,18 @@
 
     private LocalServerSocket mServerSocket;
 
+    /**
+     * Set by the child process, immediately after a call to {@code Zygote.forkAndSpecialize}.
+     */
+    private boolean mIsForkChild;
+
     ZygoteServer() {
     }
 
+    void setForkChild() {
+        mIsForkChild = true;
+    }
+
     /**
      * Registers a server socket for zygote command connections
      *
@@ -129,11 +139,8 @@
      * Runs the zygote process's select loop. Accepts new connections as
      * they happen, and reads commands from connections one spawn-request's
      * worth at a time.
-     *
-     * @throws Zygote.MethodAndArgsCaller in a child process when a main()
-     * should be executed.
      */
-    void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
+    Runnable runSelectLoop(String abiList) {
         ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
         ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
 
@@ -156,15 +163,62 @@
                 if ((pollFds[i].revents & POLLIN) == 0) {
                     continue;
                 }
+
                 if (i == 0) {
                     ZygoteConnection newPeer = acceptCommandPeer(abiList);
                     peers.add(newPeer);
                     fds.add(newPeer.getFileDesciptor());
                 } else {
-                    boolean done = peers.get(i).runOnce(this);
-                    if (done) {
-                        peers.remove(i);
-                        fds.remove(i);
+                    try {
+                        ZygoteConnection connection = peers.get(i);
+                        final Runnable command = connection.processOneCommand(this);
+
+                        if (mIsForkChild) {
+                            // We're in the child. We should always have a command to run at this
+                            // stage if processOneCommand hasn't called "exec".
+                            if (command == null) {
+                                throw new IllegalStateException("command == null");
+                            }
+
+                            return command;
+                        } else {
+                            // We're in the server - we should never have any commands to run.
+                            if (command != null) {
+                                throw new IllegalStateException("command != null");
+                            }
+
+                            // We don't know whether the remote side of the socket was closed or
+                            // not until we attempt to read from it from processOneCommand. This shows up as
+                            // a regular POLLIN event in our regular processing loop.
+                            if (connection.isClosedByPeer()) {
+                                connection.closeSocket();
+                                peers.remove(i);
+                                fds.remove(i);
+                            }
+                        }
+                    } catch (Exception e) {
+                        if (!mIsForkChild) {
+                            // We're in the server so any exception here is one that has taken place
+                            // pre-fork while processing commands or reading / writing from the
+                            // control socket. Make a loud noise about any such exceptions so that
+                            // we know exactly what failed and why.
+
+                            Slog.e(TAG, "Exception executing zygote command: ", e);
+
+                            // Make sure the socket is closed so that the other end knows immediately
+                            // that something has gone wrong and doesn't time out waiting for a
+                            // response.
+                            ZygoteConnection conn = peers.remove(i);
+                            conn.closeSocket();
+
+                            fds.remove(i);
+                        } else {
+                            // We're in the child so any exception caught here has happened post
+                            // fork and before we execute ActivityThread.main (or any other main()
+                            // method). Log the details of the exception and bring down the process.
+                            Log.e(TAG, "Caught post-fork exception in child process.", e);
+                            throw e;
+                        }
                     }
                 }
             }
diff --git a/core/java/com/android/internal/os/package.html b/core/java/com/android/internal/os/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/os/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/statusbar/package.html b/core/java/com/android/internal/statusbar/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java
index 3c1d2d6..b85b84f 100644
--- a/core/java/com/android/internal/util/FastXmlSerializer.java
+++ b/core/java/com/android/internal/util/FastXmlSerializer.java
@@ -49,18 +49,19 @@
         null,     null,     null,     null,     "&lt;",   null,     "&gt;",   null,   // 56-63
     };
 
-    private static final int BUFFER_LEN = 8192;
+    private static final int DEFAULT_BUFFER_LEN = 32*1024;
 
     private static String sSpace = "                                                              ";
 
-    private final char[] mText = new char[BUFFER_LEN];
+    private final int mBufferLen;
+    private final char[] mText;
     private int mPos;
 
     private Writer mWriter;
 
     private OutputStream mOutputStream;
     private CharsetEncoder mCharset;
-    private ByteBuffer mBytes = ByteBuffer.allocate(BUFFER_LEN);
+    private ByteBuffer mBytes;
 
     private boolean mIndent = false;
     private boolean mInTag;
@@ -68,9 +69,25 @@
     private int mNesting = 0;
     private boolean mLineStart = true;
 
+    public FastXmlSerializer() {
+        this(DEFAULT_BUFFER_LEN);
+    }
+
+    /**
+     * Allocate a FastXmlSerializer with the given internal output buffer size.  If the
+     * size is zero or negative, then the default buffer size will be used.
+     *
+     * @param bufferSize Size in bytes of the in-memory output buffer that the writer will use.
+     */
+    public FastXmlSerializer(int bufferSize) {
+        mBufferLen = (bufferSize > 0) ? bufferSize : DEFAULT_BUFFER_LEN;
+        mText = new char[mBufferLen];
+        mBytes = ByteBuffer.allocate(mBufferLen);
+    }
+
     private void append(char c) throws IOException {
         int pos = mPos;
-        if (pos >= (BUFFER_LEN-1)) {
+        if (pos >= (mBufferLen-1)) {
             flush();
             pos = mPos;
         }
@@ -79,17 +96,17 @@
     }
 
     private void append(String str, int i, final int length) throws IOException {
-        if (length > BUFFER_LEN) {
+        if (length > mBufferLen) {
             final int end = i + length;
             while (i < end) {
-                int next = i + BUFFER_LEN;
-                append(str, i, next<end ? BUFFER_LEN : (end-i));
+                int next = i + mBufferLen;
+                append(str, i, next<end ? mBufferLen : (end-i));
                 i = next;
             }
             return;
         }
         int pos = mPos;
-        if ((pos+length) > BUFFER_LEN) {
+        if ((pos+length) > mBufferLen) {
             flush();
             pos = mPos;
         }
@@ -98,17 +115,17 @@
     }
 
     private void append(char[] buf, int i, final int length) throws IOException {
-        if (length > BUFFER_LEN) {
+        if (length > mBufferLen) {
             final int end = i + length;
             while (i < end) {
-                int next = i + BUFFER_LEN;
-                append(buf, i, next<end ? BUFFER_LEN : (end-i));
+                int next = i + mBufferLen;
+                append(buf, i, next<end ? mBufferLen : (end-i));
                 i = next;
             }
             return;
         }
         int pos = mPos;
-        if ((pos+length) > BUFFER_LEN) {
+        if ((pos+length) > mBufferLen) {
             flush();
             pos = mPos;
         }
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
index b075db8..1aa32cc 100644
--- a/core/java/com/android/internal/util/Protocol.java
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -65,5 +65,6 @@
     public static final int BASE_NETWORK_MONITOR                                    = 0x00082000;
     public static final int BASE_NETWORK_FACTORY                                    = 0x00083000;
     public static final int BASE_ETHERNET                                           = 0x00084000;
+    public static final int BASE_LOWPAN                                             = 0x00085000;
     //TODO: define all used protocols
 }
diff --git a/core/java/com/android/internal/widget/package.html b/core/java/com/android/internal/widget/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/widget/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/server/net/OWNERS b/core/java/com/android/server/net/OWNERS
new file mode 100644
index 0000000..74f39a1
--- /dev/null
+++ b/core/java/com/android/server/net/OWNERS
@@ -0,0 +1,5 @@
+set noparent
+
+ek@google.com
+hugobenichi@google.com
+lorenzo@google.com
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index c4533c3..c629341 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -185,9 +185,10 @@
         "android_content_res_Configuration.cpp",
         "android_animation_PropertyValuesHolder.cpp",
         "com_android_internal_net_NetworkStatsFactory.cpp",
+        "com_android_internal_os_ClassLoaderFactory.cpp",
         "com_android_internal_os_FuseAppLoop.cpp",
-        "com_android_internal_os_PathClassLoaderFactory.cpp",
         "com_android_internal_os_Zygote.cpp",
+        "com_android_internal_os_ZygoteInit.cpp",
         "com_android_internal_util_VirtualRefBasePtr.cpp",
         "com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp",
         "hwbinder/EphemeralStorage.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 89e137b..08f30ed 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -203,9 +203,10 @@
 extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
 extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
 extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
+extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env);
 extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
-extern int register_com_android_internal_os_PathClassLoaderFactory(JNIEnv* env);
 extern int register_com_android_internal_os_Zygote(JNIEnv *env);
+extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
 
 static AndroidRuntime* gCurRuntime = NULL;
@@ -245,7 +246,7 @@
         methods, NELEM(methods));
 }
 
-int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
+int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
 {
     const JNINativeMethod methods[] = {
         { "nativeZygoteInit", "()V",
@@ -1301,7 +1302,7 @@
 
 static const RegJNIRec gRegJNI[] = {
     REG_JNI(register_com_android_internal_os_RuntimeInit),
-    REG_JNI(register_com_android_internal_os_ZygoteInit),
+    REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
     REG_JNI(register_android_os_SystemClock),
     REG_JNI(register_android_util_EventLog),
     REG_JNI(register_android_util_Log),
@@ -1402,8 +1403,9 @@
     REG_JNI(register_android_net_TrafficStats),
     REG_JNI(register_android_os_MemoryFile),
     REG_JNI(register_android_os_SharedMemory),
-    REG_JNI(register_com_android_internal_os_PathClassLoaderFactory),
+    REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
     REG_JNI(register_com_android_internal_os_Zygote),
+    REG_JNI(register_com_android_internal_os_ZygoteInit),
     REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
     REG_JNI(register_android_hardware_Camera),
     REG_JNI(register_android_hardware_camera2_CameraMetadata),
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 5a25d5e..0a0e5f4 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -130,17 +130,6 @@
     scaleDivRange(chunk->getYDivs(), chunk->numYDivs, scale, scaledHeight);
 }
 
-static SkColorType colorTypeForScaledOutput(SkColorType colorType) {
-    switch (colorType) {
-        case kUnknown_SkColorType:
-        case kIndex_8_SkColorType:
-            return kN32_SkColorType;
-        default:
-            break;
-    }
-    return colorType;
-}
-
 class ScaleCheckingAllocator : public SkBitmap::HeapAllocator {
 public:
     ScaleCheckingAllocator(float scale, int size)
@@ -149,8 +138,7 @@
 
     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
         // accounts for scale in final allocation, using eventual size and config
-        const int bytesPerPixel = SkColorTypeBytesPerPixel(
-                colorTypeForScaledOutput(bitmap->colorType()));
+        const int bytesPerPixel = SkColorTypeBytesPerPixel(bitmap->colorType());
         const int requestedSize = bytesPerPixel *
                 int(bitmap->width() * mScale + 0.5f) *
                 int(bitmap->height() * mScale + 0.5f);
@@ -334,13 +322,7 @@
         env->SetIntField(options, gOptions_heightFieldID, scaledHeight);
         env->SetObjectField(options, gOptions_mimeFieldID, mimeType);
 
-        SkColorType outColorType = decodeColorType;
-        // Scaling can affect the output color type
-        if (willScale || scale != 1.0f) {
-            outColorType = colorTypeForScaledOutput(outColorType);
-        }
-
-        jint configID = GraphicsJNI::colorTypeToLegacyBitmapConfig(outColorType);
+        jint configID = GraphicsJNI::colorTypeToLegacyBitmapConfig(decodeColorType);
         if (isHardware) {
             configID = GraphicsJNI::kHardware_LegacyBitmapConfig;
         }
@@ -397,24 +379,6 @@
         decodeAllocator = &defaultAllocator;
     }
 
-    // Construct a color table for the decode if necessary
-    sk_sp<SkColorTable> colorTable(nullptr);
-    SkPMColor* colorPtr = nullptr;
-    int* colorCount = nullptr;
-    int maxColors = 256;
-    SkPMColor colors[256];
-    if (kIndex_8_SkColorType == decodeColorType) {
-        colorTable.reset(new SkColorTable(colors, maxColors));
-
-        // SkColorTable expects us to initialize all of the colors before creating an
-        // SkColorTable.  However, we are using SkBitmap with an Allocator to allocate
-        // memory for the decode, so we need to create the SkColorTable before decoding.
-        // It is safe for SkAndroidCodec to modify the colors because this SkBitmap is
-        // not being used elsewhere.
-        colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
-        colorCount = &maxColors;
-    }
-
     SkAlphaType alphaType = codec->computeOutputAlphaType(requireUnpremultiplied);
 
     const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(),
@@ -437,7 +401,7 @@
     }
     SkBitmap decodingBitmap;
     if (!decodingBitmap.setInfo(bitmapInfo) ||
-            !decodingBitmap.tryAllocPixels(decodeAllocator, colorTable.get())) {
+            !decodingBitmap.tryAllocPixels(decodeAllocator, nullptr)) {
         // SkAndroidCodec should recommend a valid SkImageInfo, so setInfo()
         // should only only fail if the calculated value for rowBytes is too
         // large.
@@ -450,8 +414,6 @@
     SkAndroidCodec::AndroidOptions codecOptions;
     codecOptions.fZeroInitialized = decodeAllocator == &defaultAllocator ?
             SkCodec::kYes_ZeroInitialized : SkCodec::kNo_ZeroInitialized;
-    codecOptions.fColorPtr = colorPtr;
-    codecOptions.fColorCount = colorCount;
     codecOptions.fSampleSize = sampleSize;
     SkCodec::Result result = codec->getAndroidPixels(decodeInfo, decodingBitmap.getPixels(),
             decodingBitmap.rowBytes(), &codecOptions);
@@ -518,7 +480,7 @@
             outputAllocator = &defaultAllocator;
         }
 
-        SkColorType scaledColorType = colorTypeForScaledOutput(decodingBitmap.colorType());
+        SkColorType scaledColorType = decodingBitmap.colorType();
         // FIXME: If the alphaType is kUnpremul and the image has alpha, the
         // colors may not be correct, since Skia does not yet support drawing
         // to/from unpremultiplied bitmaps.
@@ -579,6 +541,9 @@
 
     if (isHardware) {
         sk_sp<Bitmap> hardwareBitmap = Bitmap::allocateHardwareBitmap(outputBitmap);
+        if (!hardwareBitmap.get()) {
+            return nullObjectReturn("Failed to allocate a hardware bitmap");
+        }
         return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags,
                 ninePatchChunk, ninePatchInsets, -1);
     }
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index fa9379e..8b4cc91 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -102,7 +102,10 @@
         cPackageInfo[i] = cString;
         env->ReleaseStringUTFChars(element, cString);
     }
-    int32_t status = VintfObject::CheckCompatibility(cPackageInfo);
+    std::string error;
+    int32_t status = VintfObject::CheckCompatibility(cPackageInfo, &error);
+    if (status)
+        LOG(WARNING) << "VintfObject.verify() returns " << status << ": " << error;
     return status;
 }
 
diff --git a/core/jni/com_android_internal_os_PathClassLoaderFactory.cpp b/core/jni/com_android_internal_os_ClassLoaderFactory.cpp
similarity index 85%
rename from core/jni/com_android_internal_os_PathClassLoaderFactory.cpp
rename to core/jni/com_android_internal_os_ClassLoaderFactory.cpp
index a7a912c..7052e5f 100644
--- a/core/jni/com_android_internal_os_PathClassLoaderFactory.cpp
+++ b/core/jni/com_android_internal_os_ClassLoaderFactory.cpp
@@ -39,13 +39,13 @@
       reinterpret_cast<void*>(createClassloaderNamespace_native) },
 };
 
-static const char* const kPathClassLoaderFactoryPathName = "com/android/internal/os/PathClassLoaderFactory";
+static const char* const kClassLoaderFactoryPathName = "com/android/internal/os/ClassLoaderFactory";
 
 namespace android
 {
 
-int register_com_android_internal_os_PathClassLoaderFactory(JNIEnv* env) {
-    return RegisterMethodsOrDie(env, kPathClassLoaderFactoryPathName, g_methods, NELEM(g_methods));
+int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, kClassLoaderFactoryPathName, g_methods, NELEM(g_methods));
 }
 
 } // namespace android
diff --git a/core/jni/com_android_internal_os_FuseAppLoop.cpp b/core/jni/com_android_internal_os_FuseAppLoop.cpp
index 2d5026f..8837df5 100644
--- a/core/jni/com_android_internal_os_FuseAppLoop.cpp
+++ b/core/jni/com_android_internal_os_FuseAppLoop.cpp
@@ -142,14 +142,14 @@
 }
 
 void com_android_internal_os_FuseAppLoop_replyLookup(
-        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) {
+        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jlong size) {
     if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyLookup(unique, inode, size)) {
         reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
     }
 }
 
 void com_android_internal_os_FuseAppLoop_replyGetAttr(
-        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jint size) {
+        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jlong size) {
     if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyGetAttr(
             unique, inode, size, S_IFREG | 0777)) {
         reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
new file mode 100644
index 0000000..258a55c
--- /dev/null
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "Zygote"
+
+#include <ui/GraphicBufferMapper.h>
+
+#include "core_jni_helpers.h"
+
+namespace {
+
+void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jclass) {
+    android::GraphicBufferMapper::preloadHal();
+    // Add preloading here for other HALs that are (a) always passthrough, and
+    // (b) loaded by most app processes.
+}
+
+const JNINativeMethod gMethods[] = {
+    { "nativePreloadAppProcessHALs", "()V",
+      (void*)android_internal_os_ZygoteInit_nativePreloadAppProcessHALs },
+};
+
+}  // anonymous namespace
+
+namespace android {
+
+int register_com_android_internal_os_ZygoteInit(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "com/android/internal/os/ZygoteInit",
+            gMethods, NELEM(gMethods));
+}
+
+}  // namespace android
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a3cb350..324cd0d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1706,19 +1706,18 @@
     <!-- Allows an application to manage embedded subscriptions (those on a eUICC) through
          EuiccManager APIs.
          <p>Protection level: signature|privileged|development
-         TODO(b/35851809): Mark this as a SystemApi.
+         TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
          @hide -->
-    <permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
+    <permission android:name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
                 android:protectionLevel="signature|privileged|development" />
 
     <!-- Must be required by an EuiccService to ensure that only the system can bind to it.
          <p>Protection level: signature
-         TODO(b/35851809): Mark this as a SystemApi.
+         TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
          @hide -->
-    <permission android:name="android.permission.BIND_EUICC_SERVICE"
+    <permission android:name="com.android.permission.BIND_EUICC_SERVICE"
                 android:protectionLevel="signature" />
 
-
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
     <!-- ================================== -->
@@ -3215,6 +3214,11 @@
     <permission android:name="android.permission.MANAGE_NOTIFICATIONS"
                 android:protectionLevel="signature" />
 
+    <!-- Allows notifications to be colorized
+         <p>Not for use by third-party applications. @hide -->
+    <permission android:name="android.permission.USE_COLORIZED_NOTIFICATIONS"
+                android:protectionLevel="signature|setup" />
+
     <!-- Allows access to keyguard secure storage.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"
diff --git a/core/res/res/drawable/ic_lock_bugreport.xml b/core/res/res/drawable/ic_lock_bugreport.xml
index b0c32e0..5501254 100644
--- a/core/res/res/drawable/ic_lock_bugreport.xml
+++ b/core/res/res/drawable/ic_lock_bugreport.xml
@@ -1,7 +1,7 @@
 <!--
-Copyright (C) 2014 The Android Open Source Project
+    Copyright (C) 2017 The Android Open Source Project
 
-   Licensed under the Apache License, Version 2.0 (the "License");
+    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
 
@@ -14,12 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32dp"
-        android:height="32dp"
+        android:width="24.0dp"
+        android:height="24.0dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0"
         android:tint="?attr/colorControlNormal">
     <path
-        android:fillColor="@color/white"
-        android:pathData="M20.0,8.0l-2.8,0.0c-0.5,-0.8 -1.1,-1.5 -1.8,-2.0L17.0,4.4L15.6,3.0l-2.2,2.2C13.0,5.1 12.5,5.0 12.0,5.0s-1.0,0.1 -1.4,0.2L8.4,3.0L7.0,4.4L8.6,6.0C7.9,6.5 7.3,7.2 6.8,8.0L4.0,8.0l0.0,2.0l2.1,0.0C6.0,10.3 6.0,10.7 6.0,11.0l0.0,1.0L4.0,12.0l0.0,2.0l2.0,0.0l0.0,1.0c0.0,0.3 0.0,0.7 0.1,1.0L4.0,16.0l0.0,2.0l2.8,0.0c1.0,1.8 3.0,3.0 5.2,3.0s4.2,-1.2 5.2,-3.0L20.0,18.0l0.0,-2.0l-2.1,0.0c0.1,-0.3 0.1,-0.7 0.1,-1.0l0.0,-1.0l2.0,0.0l0.0,-2.0l-2.0,0.0l0.0,-1.0c0.0,-0.3 0.0,-0.7 -0.1,-1.0L20.0,10.0L20.0,8.0zM14.0,16.0l-4.0,0.0l0.0,-2.0l4.0,0.0L14.0,16.0zM14.0,12.0l-4.0,0.0l0.0,-2.0l4.0,0.0L14.0,12.0z"/>
+        android:fillColor="#FF000000"
+        android:pathData="M20.0,8.0l-2.81,0.0a5.985,5.985 0.0,0.0 0.0,-1.82 -1.96l0.93,-0.93a0.99,0.996 0.0,1.0 0.0,-1.41 -1.41l-1.47,1.47C12.96,5.06 12.49,5.0 12.0,5.0s-0.9,0.06 -1.4,0.17L9.12,3.7a0.99,0.996 0.0,1.0 0.0,-1.41 1.41l0.9,0.92C7.88,6.55 7.26,7.22 6.81,8.0L4.0,8.0c-0.55,0.0 -1.0,0.45 -1.0,1.0s0.45,1.0 1.0,1.0l2.09,0.0c0.0,0.33 0.0,0.66 -0.09,1.0l0.0,1.0L4.0,12.0c-0.55,0.0 -1.0,0.45 -1.0,1.0s0.45,1.0 1.0,1.0l2.0,0.0l0.0,1.0c0.0,0.3 0.0,0.6 0.09,1.0L4.0,16.0c-0.55,0.0 -1.0,0.45 -1.0,1.0s0.45,1.0 1.0,1.0l2.81,0.0c1.04,1.79 2.97,3.0 5.19,3.0s4.15,-1.21 5.19,-3.0L20.0,18.0c0.55,0.0 1.0,-0.45 1.0,-1.0s-0.45,-1.0 -1.0,-1.0l-2.09,0.0c0.05,-0.3 0.09,-0.6 0.09,-1.0l0.0,-1.0l2.0,0.0c0.55,0.0 1.0,-0.45 1.0,-1.0s-0.45,-1.0 -1.0,-1.0l-2.0,0.0l0.0,-1.0c0.0,-0.34 -0.04,-0.67 -0.09,-1.0L20.0,10.0c0.55,0.0 1.0,-0.45 1.0,-1.0s-0.45,-1.0 -1.0,-1.0zm-6.0,8.0l-4.0,0.0l0.0,-2.0l4.0,0.0l0.0,2.0zm0.0,-4.0l-4.0,0.0l0.0,-2.0l4.0,0.0l0.0,2.0z"/>
 </vector>
diff --git a/core/res/res/drawable/ic_lock_power_off.xml b/core/res/res/drawable/ic_lock_power_off.xml
index babd1be..7e5676bd 100644
--- a/core/res/res/drawable/ic_lock_power_off.xml
+++ b/core/res/res/drawable/ic_lock_power_off.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 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.
@@ -16,10 +16,13 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24.0dp"
         android:height="24.0dp"
-        android:viewportHeight="24.0"
         android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
         android:tint="?attr/colorControlNormal">
     <path
         android:fillColor="#FF000000"
-        android:pathData="M13.0,3.0l-2.0,0.0l0.0,10.0l2.0,0.0L13.0,3.0zm4.83,2.17l-1.42,1.42C17.99,7.86 19.0,9.81 19.0,12.0c0.0,3.87 -3.13,7.0 -7.0,7.0s-7.0,-3.13 -7.0,-7.0c0.0,-2.19 1.01,-4.14 2.58,-5.42L6.17,5.17C4.23,6.82 3.0,9.26 3.0,12.0c0.0,4.97 4.03,9.0 9.0,9.0s9.0,-4.03 9.0,-9.0c0.0,-2.74 -1.23,-5.18 -3.17,-6.83z"/>
+        android:pathData="M12.0,3.0c-0.6,0.0 -1.0,0.4 -1.0,1.0l0.0,8.0c0.0,0.6 0.4,1.0 1.0,1.0s1.0,-0.4 1.0,-1.0L13.0,4.0c0.0,-0.6 -0.4,-1.0 -1.0,-1.0z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M17.1,5.9c-0.4,0.4 -0.4,1.0 0.0,1.4 1.3,1.4 2.1,3.4 1.8,5.6 -0.4,3.2 -3.0,5.7 -6.2,6.1 -4.0,0.4 -7.7,-2.9 -7.7,-7.0 0.0,-1.0 0.7,-3.5 1.9,-4.0 0.4,-0.4 0.4,-1.0 0.0,-1.4 -0.4,-0.4 -1.0,-0.4 -1.4,0.0C4.0,7.4 3.1,9.5 3.0,11.7c-0.1,4.9 3.8,9.1 8.7,9.3 5.0,0.2 9.3,-3.9 9.3,-9.0 0.0,-2.4 -0.9,-4.5 -2.4,-6.1 -0.4,-0.4 -1.1,-0.4 -1.5,0.0z"/>
 </vector>
diff --git a/core/res/res/drawable/ic_restart.xml b/core/res/res/drawable/ic_restart.xml
index 47ac483..30d98a5 100644
--- a/core/res/res/drawable/ic_restart.xml
+++ b/core/res/res/drawable/ic_restart.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2016 The Android Open Source Project
+    Copyright (C) 2017 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.
@@ -16,13 +16,13 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24.0dp"
         android:height="24.0dp"
-        android:viewportHeight="24.0"
         android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
         android:tint="?attr/colorControlNormal">
     <path
         android:fillColor="#FF000000"
-        android:pathData="M12.0,4.0L12.0,1.0L8.0,5.0l4.0,4.0L12.0,6.0c3.9,0.0 7.0,3.1 7.0,7.0c0.0,3.9 -3.1,7.0 -7.0,7.0l0.0,2.0c5.0,0.0 9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0z"/>
+        android:pathData="M10.61,17.83C7.97,17.2 6.0,14.83 6.0,12.0c0.0,-0.71 0.11,-1.34 0.35,-1.93c0.2,-0.51 -0.05,-1.09 -0.56,-1.3c-0.52,-0.21 -1.1,0.05 -1.3,0.56C4.16,10.16 4.0,11.03 4.0,12.0c0.0,3.87 2.76,7.1 6.42,7.84c0.3,0.06 0.58,-0.19 0.58,-0.5l0.0,-1.03C11.0,18.08 10.83,17.88 10.61,17.83z"/>
     <path
         android:fillColor="#FF000000"
-        android:pathData="M5.0,12.9C5.0,11.0 5.8,9.2 7.2,7.9L5.8,6.4C4.0,8.1 3.0,10.5 3.0,12.9c0.0,4.0 2.7,7.6 6.5,8.7l0.5,-1.9C7.1,18.8 5.0,16.1 5.0,12.9z"/>
+        android:pathData="M12.01,4.0L12.01,1.9c0.0,-0.45 -0.54,-0.67 -0.86,-0.36L7.77,4.93c-0.39,0.39 -0.39,1.02 0.0,1.41l3.39,3.39c0.31,0.31 0.85,0.09 0.85,-0.35L12.01,6.0C15.32,6.01 18.0,8.69 18.0,12.0c0.0,2.83 -1.97,5.2 -4.61,5.83C13.17,17.88 13.0,18.08 13.0,18.31l0.0,1.03c0.0,0.31 0.28,0.56 0.58,0.5C17.24,19.1 20.0,15.87 20.0,12.0C20.0,7.59 16.42,4.01 12.01,4.0z"/>
 </vector>
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index dc47dcf..f3d4a84 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -34,6 +34,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerHorizontal="true"
+            android:layout_centerVertical="true"
             android:paddingTop="@dimen/timepicker_radial_picker_top_margin"
             android:orientation="horizontal">
 
diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml
index 9baa32c..6c1271d 100644
--- a/core/res/res/layout/chooser_row.xml
+++ b/core/res/res/layout/chooser_row.xml
@@ -18,11 +18,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:orientation="horizontal"
-              android:layout_width="match_parent" android:layout_height="wrap_content"
-              android:minHeight="80dp"
+              android:layout_width="match_parent"
+              android:layout_height="100dp"
               android:gravity="start|top"
-              android:paddingTop="8dp"
-              android:paddingBottom="8dp"
               android:paddingStart="@dimen/chooser_grid_padding"
               android:paddingEnd="@dimen/chooser_grid_padding"
               android:weightSum="4">
diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml
index 305c8b0..71c153f 100644
--- a/core/res/res/layout/resolve_grid_item.xml
+++ b/core/res/res/layout/resolve_grid_item.xml
@@ -18,10 +18,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:orientation="vertical"
-              android:layout_width="0dp"
+              android:layout_width="76dp"
               android:layout_height="wrap_content"
-              android:layout_weight="1"
-              android:minWidth="80dp"
+              android:minHeight="100dp"
               android:gravity="center"
               android:paddingTop="8dp"
               android:paddingBottom="8dp"
@@ -49,7 +48,7 @@
     <TextView android:id="@android:id/text1"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
-              android:layout_marginTop="8dp"
+              android:layout_marginTop="4dp"
               android:layout_marginLeft="4dp"
               android:layout_marginRight="4dp"
               android:textAppearance="?attr/textAppearanceSmall"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0e7b5c0..a35d61d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ontruim kusgebiede en riviergebiede dadelik en gaan na \'n veiliger plek, soos \'n hoogliggende omgewing."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bly kalm en soek skuiling naby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Noodboodskappetoets"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Antwoord"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM word nie toegelaat nie"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM is nie opgestel nie"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8356efa..9f67ea2 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ወዲያውኑ ከባህር ዳርቻ አካባቢዎች እና የወንዝ ዳርቻ አካባቢዎች ይውጡና እንደ ከፍ ያለ መሬት ያሉ ከአደጋ የተሻለ ደህንነት ወዳቸው ቦታዎች ይሂዱ።"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ረጋ ይበሉና በአቅራቢያ ያለ መጠለያ ይፈልጉ።"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"የአስቸኳይ አደጋ መልእክቶች ሙከራ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ምላሽ ስጥ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ሲም አይፈቀድም"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ሲም አልቀረበም"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 26e43ca..cc27756 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1905,8 +1905,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"يُرجى النزوح في الحال من المناطق الساحلية وضفاف النهر إلى مكان أكثر أمانًا مثل الأراضي المرتفعة."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"يُرجى الثبات والبحث عن ملاذ بالجوار."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"اختبار رسائل الطوارئ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"الرد"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"‏غير مسموح باستخدام SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"‏لم يتم تقديم SIM"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 10198de..dad5802 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Dərhal sahil bölgələrindən və çay kənarı ərazilərdən daha təhlükəsiz yüksək yerlərə evakuasiya edin."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sakit qalın və yaxınlıqda sığınacaq axtarın."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Təcili mesaj testi"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Cavablayın"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-ə icazə verilmir"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM təmin edilməyib"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5849536..5f1ca49 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1803,8 +1803,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se sklonite iz priobalnih regiona i oblasti pored reka na neko bezbednije mesto, na primer, na neko uzvišenje."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni i potražite sklonište u okolini."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testiranje poruka u hitnim slučajevima"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odgovori"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kartica nije dozvoljena"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kartica nije podešena"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 316ee49..7ec4751 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1837,8 +1837,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Неадкладна эвакуіруйцеся з прыбярэжных раёнаў у больш бяспечнае месца, напрыклад на ўзвышша."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Заставайцеся спакойнымі і пашукайце прытулак паблізу."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Праверка экстранных паведамленняў"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Адказаць"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-карта не дапускаецца"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-карты няма"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 83ae338..e61e49c 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Евакуирайте се незабавно от крайбрежните и крайречните региони на по-безопасно място – например такова с по-високо надморско равнище."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Запазете спокойствие и потърсете убежище в района."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тест за спешни съобщения"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Отговор"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картата не е разрешена"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM картата не е обезпечена"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 3e487b9..939a45c 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"উপকূলবর্তী এবং নদীর পাশের অঞ্চল থেকে অবিলম্বে উঁচু কোনো জায়গার দিকে যান।"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"শান্ত থাকুন, আশেপাশে আশ্রয় খুঁজুন।"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"বিপদকালীন বার্তাগুলির পরীক্ষা"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"উত্তর দিন"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"সিম অনুমোদিত নয়"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"সিম প্রস্তুত নয়"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 4539121..186cbbf 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -84,7 +84,7 @@
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema govornih/hitnih usluga"</string>
     <string name="RestrictedStateContent" msgid="4278821484643362350">"Trenutno nije u ponudi mobilne mreže na vašoj lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nije moguće dosegnuti mrežu"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Da poboljšate prijem, pokušajte promijeniti odabrani tip u meniju Postavke &lt; Mreža i internet &lt; Mobilne mreže &lt; Preferirani tip mreže."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Da poboljšate prijem, pokušajte promijeniti odabranu vrstu u meniju Postavke &lt; Mreža i internet &lt; Mobilne mreže &lt; Preferirana vrsta mreže."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozorenja"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmjeravanje poziva"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način rada za hitni povratni poziv"</string>
@@ -195,10 +195,10 @@
     <string name="reboot_to_update_title" msgid="6212636802536823850">"Ažuriranje sistema Android"</string>
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Priprema za ažuriranje..."</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Obrađuje se paket ažuriranja..."</string>
-    <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Ponovno se pokreće..."</string>
+    <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Ponovno pokretanje......"</string>
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"Vraćanje na fabričke postavke"</string>
-    <string name="reboot_to_reset_message" msgid="2432077491101416345">"Ponovno se pokreće..."</string>
-    <string name="shutdown_progress" msgid="2281079257329981203">"Gašenje u toku…"</string>
+    <string name="reboot_to_reset_message" msgid="2432077491101416345">"Ponovno pokretanje......"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Isključivanje...…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Vaš tablet će se isključiti."</string>
     <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"TV će se isključiti."</string>
     <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Sat će se isključiti."</string>
@@ -1281,7 +1281,7 @@
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"Omogućava aplikaciji da traži dozvolu za zanemarivanje optimizacije baterije za tu aplikaciju."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Dodirnite dvaput za kontrolu uvećanja"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Dodavanje vidžeta nije uspjelo."</string>
-    <string name="ime_action_go" msgid="8320845651737369027">"Počni"</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Započni"</string>
     <string name="ime_action_search" msgid="658110271822807811">"Pretraži"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"Poslati"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Naprijed"</string>
@@ -1700,7 +1700,7 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skupi"</string>
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne ometaj"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Odmor"</string>
-    <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Radni dan uveče"</string>
+    <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Radni dan uvečer"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Vikend"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Događaj"</string>
     <string name="muted_by" msgid="6147073845094180001">"Ton isključila aplikacija <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
@@ -1809,8 +1809,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se evakuirajte iz priobalnih područja i područja oko rijeka na sigurnije mjesto kao što su viši predjeli."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite smireni i potražite sklonište u blizini."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test poruka za hitne slučajeve"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odgovori"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kartica nije dozvoljena"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kartica nije dodijeljena"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 7036603..0dbae8b 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandona immediatament les regions costaneres i riberenques, i cerca un lloc més segur, com ara un terreny elevat."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma i busca refugi a prop."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prova de missatges d\'emergència"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Respon"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM no compatible"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM no proporcionada"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 04190d5..a3072dc 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1837,8 +1837,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Z pobřežních oblastí a okolí řek se co nejrychleji přesuňte do většího bezpečí (například na výše položené místo)."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachovejte klid a přesuňte se na bezpečné místo v okolí."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test nouzových zpráv"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odpovědět"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karta není povolena"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karta není poskytována"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 3834d7c..22d4c3a 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Forlad omgående kyst- og flodområder, og søg mod et mere sikkert sted, f.eks. et højere terræn."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bevar roen, og søg ly i nærheden."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test af nødbeskeder"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svar"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kortet har ikke adgangstilladelse"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kortet er ikke aktiveret"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 27bd4a9..b223224 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Verlasse so schnell wie möglich Flussufer und Küstengebiete und suche in einer höher gelegenen Umgebung Schutz."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bleibe ruhig und suche in der Nähe Schutz."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test der Notfallwarnungen"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Antworten"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-Karte nicht zulässig"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM nicht eingerichtet"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 2421797..88440cb 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Εκκενώστε αμέσως τις παράκτιες περιοχές και τις περιοχές δίπλα σε ποτάμια και μετακινηθείτε σε ένα ασφαλέστερο μέρος, όπως περιοχές με υψόμετρο."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Μείνετε ψύχραιμοι και αναζητήστε κάποιο κοντινό καταφύγιο."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Δοκιμαστικό μήνυμα έκτακτης ανάγκης"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Απάντηση"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Η κάρτα SIM δεν επιτρέπεται"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Δεν παρέχεται κάρτα SIM"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index f546256..9b5528c 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f546256..9b5528c 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f546256..9b5528c 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 68fb34b..5bf170b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacúa inmediatamente las regiones costeras y ribereñas en busca de un lugar seguro, como un terreno elevado."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma y busca un refugio cercano."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prueba de mensajes de emergencia"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM no permitida"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM no provista"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 95f0dff..e8df21f 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Aléjate inmediatamente de las zonas costeras y situadas junto a un río para dirigirte hacia un lugar más seguro, por ejemplo, un terreno elevado."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantén la calma y busca refugio en algún lugar cercano."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prueba de mensajes de emergencia"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM no compatible"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM no proporcionada"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index bd05d64..b4d4cff5 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakueeruge ranniku ja jõekallaste piirkondadest viivitamatult ohutusse kohta, näiteks kõrgematesse kohtadesse."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Jääge rahulikuks ja otsige lähedusest peavarju."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Hädaabisõnumite test"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Vasta"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kaart pole lubatud"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kaart on ettevalmistamata"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 46788fb..9aeae4a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"فوراً مناطق ساحلی و محدوده رودخانه را ترک کنید و به جایی امن، مثل ارتفاعات بروید."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"آرام باشید و پناهگاهی در این اطراف پیدا کنید."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"آزمایش پیام‌های اضطراری"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"پاسخ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"سیم‌کارت مجاز نیست"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"سیم‌کارت مجوز لازم را ندارد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3459e39..44c5efa 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1408,7 +1408,7 @@
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Aina"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Vain kerran"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ei tue työprofiilia"</string>
-    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet-laite"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tabletti"</string>
     <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"Televisio"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Puhelin"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Kuulokkeet"</string>
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Siirry heti rannikkoalueilta ja jokien varsilta korkeampiin tai muuten turvallisempiin paikkoihin."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Pysy rauhallisena ja hakeudu lähimpään suojapaikkaan."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Hätäilmoitustesti"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Vastaa"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kortti estetty"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kortti ei käyttäjien hallinnassa"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7d27a5b..728de05 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Évacuez immédiatement les zones côtières et les berges des fleuves, et réfugiez-vous dans un endroit plus sûr, comme un terrain surélevé."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Restez calme et cherchez un abri à proximité."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test de messages d\'urgence"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Répondre"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Carte SIM non autorisée"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Carte SIM non configurée"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 4352845..8745c64 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"દરિયાકિનારાના પ્રદેશો તથા નદીકાંઠાના વિસ્તારો ખાલી કરીને તાત્કાલિક સુરક્ષિત ઊંચા સ્થાન પર જાઓ."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"શાંત રહો અને નજીકમાં આશ્રય લો."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"કટોકટી સંદેશાઓનું પરીક્ષણ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"જવાબ આપો"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM મંજૂર નથી"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIMની જોગવાઈ કરી નથી"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 391ad9f..f0732d4 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"तटीय क्षेत्रों और नदी के किनारे वाले क्षेत्रों को जल्द से जल्द खाली करके किसी सुरक्षित ऊंची जगह पर चले जाएं."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शांत रहें और आस-पास आश्रय खोजें."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आपातकालीन संदेश परीक्षण"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाब दें"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM की अनुमति नहीं है"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM का प्रावधान नहीं किया गया है"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index f43c600..094af8d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1803,8 +1803,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Odmah se evakuirajte s obalnih područja i područja uz rijeku na sigurnije mjesto, primjerice povišeno područje."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Ostanite mirni i potražite sklonište u blizini."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test hitnih poruka"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odgovori"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM nije dopušten"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Ne pruža se usluga za SIM"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 285babe..29a79e5 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Azonnal meneküljön biztonságosabb helyre a tengerparti, illetve folyóparti területekről, például valamilyen magaslatra."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Őrizze meg nyugalmát, és keressen menedéket a közelben."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Vészhelyzetben küldött üzenetek tesztelése"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Válasz"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"A SIM-kártya nem engedélyezett"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Nem engedélyezett SIM-kártya"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 02da2cc..5b741ca 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ափամերձ և գետափնյա տարածքներից անմիջապես էվակուացվեք դեպի ավելի ապահով վայրեր (օրինակ՝ բարձրադիր գոտիներ):"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Պահպանեք հանգստությունը և մոտակայքում ապաստարան փնտրեք:"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Արտակարգ իրավիճակների հաղորդագրությունների թեստ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Պատասխանել"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM քարտի օգտագործումն արգելված է"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM քարտը նախապատրաստված չէ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 15ea8d2..81fe247 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuasi segera dari daerah pesisir dan area tepi sungai ke tempat yang lebih aman seperti dataran tinggi."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tetap tenang dan cari tempat berlindung terdekat."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Tes pesan darurat"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Balas"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM tidak diizinkan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM tidak di-provisioning"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 2e0fa2e..2ce334e 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Fólk sem statt er á strandsvæðum eða við ár á tafarlaust að leita öryggis á svæðum sem eru í meiri hæð yfir sjávarmáli."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Sýndu stillingu og leitaðu skjóls."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prófun neyðarskilaboða"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svara"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kort er ekki leyft"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-korti ekki úthlutað"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 5dcd3aaf..29ebdd8 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuare immediatamente le zone costiere e in riva ai fiumi e recarsi in un luogo più sicuro, ad esempio un\'altura."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantieni la calma e cerca riparo nelle vicinanze."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testo messaggi di emergenza"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Rispondi"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Scheda SIM non consentita"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Scheda SIM non predisposta"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index c34e09e..0dcc4e0 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"沿岸部の方はただちに高台へ避難してください"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"強い揺れと津波に注意してください"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"テスト用緊急速報メール"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"返信"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM 使用不可"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM には対応していません"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 6bd2ce1..0ff01ab 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"დაუყოვნებლივ გადაინაცვლეთ სანაპირო რეგიონებიდან და მდინარისპირა ტერიტორიებიდან უსაფრთხო ადგილზე (მაგალითად, შემაღლებულ ადგილზე)."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"შეინარჩუნეთ სიმშვიდე და იპოვეთ ახლომდებარე თავშესაფარი."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"სატესტო საგანგებო შეტყობინება"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"პასუხი"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM ბარათი დაუშვებელია"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM ბარათი უზრუნველყოფილი არ არის"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 70801fa..08e1e91 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Жағалау аймақтан биіктеу қауіпсіз жерге дереу көшіңіз."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Сабыр сақтап, жақын жерден баспана іздеңіз."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Төтенше хабарлар сынағы"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Жауап"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картасына рұқсат етілмеген"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM картасы белсендірілмеген"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 76f0602..f841721 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1771,8 +1771,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ភៀសខ្លួនជាបន្ទាន់ពីតំបន់ឆ្នេរ និងតំបន់តាមមាត់ទន្លេទៅកាន់កន្លែងដែលមានសុវត្ថិភាពជាងនេះ ដូចជាទីទួលណាមួយ។"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"សូមរក្សាភាពស្ងប់ស្ងាត់ ហើយស្វែងរកជម្រកសុវត្ថិភាពដែលនៅជិត។"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"សារសាកល្បងពេលមានអាសន្ន"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ឆ្លើយតប"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"មិន​អនុញ្ញាត​សីុមកាត​ទេ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"សីុម​មិន​ត្រូវបាន​ផ្តល់ជូន​ទេ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index fad951e..7527362 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ಕರಾವಳಿ ಪ್ರದೇಶಗಳು ಮತ್ತು ನದಿ ತೀರಗಳಿಂದ ತಕ್ಷಣವೇ ಎತ್ತರದ ಪ್ರದೇಶಗಳಂತಹ ಸುರಕ್ಷಿತ ಸ್ಥಳಕ್ಕೆ ಹೋಗಿ."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ಶಾಂತರಾಗಿರಿ ಮತ್ತು ಸಮೀಪದಲ್ಲೆಲ್ಲಾದರೂ ಆಶ್ರಯ ಪಡೆದುಕೊಳ್ಳಿ."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"ತುರ್ತು ಸಂದೇಶಗಳ ಪರೀಕ್ಷೆ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ಪ್ರತ್ಯುತ್ತರ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ಸಿಮ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ಸಿಮ್ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 9685e83..bab4519 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"즉시 해안 지대나 강가에서 떨어져 고지대 등 안전한 장소로 대피하세요."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"침착하게 가까운 대피소를 찾으세요."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"긴급 메시지 테스트"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"답장"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM이 허용되지 않음"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM이 프로비저닝되지 않음"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index b9e143c..2842537 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Деңиз жана дарыя жээгинде жайгашкан аймактардан бийик тоо сыяктуу коопсуз жерге тезинен чыгып кетиңиз."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Эс алып, жакын жерден калканч издеңиз."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Өзгөчө кырдаалда жөнөтүлүүчү билдирүүлөрдү сыноо"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Жооп берүү"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картаны колдонууга тыюу салынган"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM карта таанылган жок"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f10d025..a31dcc7 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1837,8 +1837,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Nedelsdami pasitraukite nuo pakrančių ir paupių. Eikite į saugią vietą, pvz., vietą, kuri yra aukštai."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Nesijaudinkite ir ieškokite prieglobsčio netoliese."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Kritinės padėties pranešimo bandymas"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Atsakyti"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM kortelė neleidžiama"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM kortelė neteikiama"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index c9e9e1f7..8cc3d90 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1803,8 +1803,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Nekavējoties pametiet piekrastes un upju zonas un dodieties uz drošākām (piemēram, augstākām) vietām."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Saglabājiet mieru un meklējiet tuvumā patvērumu."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Ārkārtas ziņojuma pārbaude"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Atbildēt"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karti nav atļauts izmantot"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karte netiek nodrošināta"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 6b68427..efac042 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1772,8 +1772,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Итна евакуација од крајбрежните региони и областите покрај реки на побезбедно место, како на пр., терени на повисока надморска височина."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Бидете смирени и побарајте засолниште во близина."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тестирање пораки за итни случаи"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Одговори"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Не е дозволена SIM-картичка"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Не е обезбедена SIM-картичка"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 344f9f2..4f8d39d 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"തീരപ്രദേശങ്ങളിൽ നിന്നും നദിക്കരകളിൽ നിന്നും ആളുകളെ ഉടനടി ഒഴിപ്പിച്ച് ഉയർന്ന ഭൂമിയിൽ എത്തിക്കുക."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"പരിഭ്രമിക്കാതിരിക്കുക, അടുത്തുള്ള അഭയകേന്ദ്രം തേടുക."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"അടിയന്തര സന്ദേശ ടെസ്റ്റ്"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"മറുപടി നൽകുക"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM അനുവദനീയമല്ല"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM പ്രൊവിഷൻ ചെയ്തിട്ടില്ല"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index c9a5853..65b6b5b 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1767,8 +1767,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Эргийн бүс, голын эргийн бүсээс өндөрлөг газар зэрэг аюулгүй газар руу нэн даруй шилжинэ үү."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Тайван байж, ойролцоох нуугдах газар хайна уу."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Онцгой байдлын зурвасын тест"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Хариу бичих"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM боломжгүй"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-г хийгээгүй"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index cd9124a..ea3705f 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"किनारपट्टीचे प्रदेश आणि नदीकाठची क्षेत्रे त्वरित रिकामी करून उंच मैदानासारख्या अधिक सुरक्षित ठिकाणी जा."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शांत रहा आणि जवळपास निवारा शोधा."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आणीबाणी संदेश चाचणी"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"प्रत्युत्तर द्या"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"सिमला अनुमती नाही"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"सिमसाठी तरतूद नाही"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 19bc7d7..f322d4e 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Segera beredar dari kawasan pinggir laut dan tepi sungai dan berpindah ke tempat yang lebih selamat seperti kawasan tinggi."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Bertenang dan cari perlindungan di kawasan yang berdekatan."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Ujian mesej kecemasan"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Balas"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM tidak dibenarkan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM tidak diperuntukkan"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f24ab13..7234cd9 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ကမ်းရိုးတန်းနှင့် မြစ်ကမ်းရိုးတစ်လျှောက်ရှိ နေရာဒေသတို့မှ ချက်ချင်းထွက်ခွာပြီး ဘေးကင်းရာကုန်းမြင့်ဒေသသို့ ပြောင်းရွှေ့ပါ။"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"စိတ်ငြိမ်ငြိမ်ထားပြီး အနီးအနားတဝိုက်တွင် ခိုနားစရာ နေရာရှာပါ။"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"အရေးပေါ် မက်ဆေ့ဂျ် စမ်းသပ်မှု"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"စာပြန်ရန်"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ဆင်းမ်ကို ခွင့်မပြုပါ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 72ad6d1..dabe298 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuer umiddelbart fra kyst- og elveområder til et tryggere sted, for eksempel høyt terreng."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hold deg rolig og søk ly i nærheten."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test av nødmeldinger"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svar"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kortet er ikke tillatt"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kortet er ikke klargjort"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index c576c89..44f17bcb 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1775,8 +1775,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"तटीय क्षेत्र र नदीछेउका ठाउँहरू छाडी उच्च सतहमा अवस्थित कुनै अझ सुरक्षित ठाउँमा जानुहोस्।"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आपतकालीन सन्देशहरूको परीक्षण"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाफ दिनुहोस्"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM लाई अनुमति छैन"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM को प्रावधान छैन"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index d690fc6..3c1f067 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Verlaat kustgebieden en rivieroevers onmiddellijk en zoek een hoger gelegen gebied op."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Blijf kalm en zoek onderdak in de buurt."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test voor noodberichten"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Beantwoorden"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Simkaart niet toegestaan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Simkaart niet geregistreerd"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 0a237b1..64d267e 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ਤੁਰੰਤ ਤੱਟੀ ਖੇਤਰਾਂ ਅਤੇ ਨਦੀ ਦੇ ਕਿਨਾਰੇ ਵਾਲੇ ਖੇਤਰਾਂ ਨੂੰ ਖਾਲੀ ਕਰ ਕੇ ਕਿਸੇ ਸੁਰੱਖਿਅਤ ਸਥਾਨ \'ਤੇ ਚਲੇ ਜਾਓ ਜਿਵੇਂ ਕਿ ਉੱਚੀ ਜ਼ਮੀਨ।"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ਸ਼ਾਂਤ ਰਹੋ ਅਤੇ ਆਸ-ਪਾਸ ਪਨਾਹ ਮੰਗੋ।"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"ਸੰਕਟਕਾਲੀਨ ਸੰਦੇਸ਼ ਟੈਸਟ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ਜਵਾਬ ਦਿਓ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM ਦੀ ਵਿਵਸਥਾ ਨਹੀਂ ਹੈ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index b730e3c..1747f27 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1448,7 +1448,7 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Zobacz wszystkie"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Wybierz działanie"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Udostępnij przez:"</string>
-    <string name="sending" msgid="3245653681008218030">"Wysyłanie..."</string>
+    <string name="sending" msgid="3245653681008218030">"Wysyłam..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Odebrać połączenie?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Zawsze"</string>
@@ -1837,8 +1837,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Niezwłocznie ewakuuj się z regionów nabrzeżnych i położonych przy rzekach w bezpieczniejsze miejsce, np. na wzniesienie."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachowaj spokój i poszukaj schronienia w pobliżu."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test komunikatów alarmowych"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odpowiedz"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Niedozwolona karta SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Nieobsługiwana karta SIM"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index a373b45..05af326 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Saia imediatamente de regiões costeiras e áreas ribeirinhas e vá para um lugar mais seguro, como terrenos elevados."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Fique calmo e procure um abrigo por perto."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Teste de mensagens de emergência"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM não permitido"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM não aprovisionado"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 4c3399d..04a78ca 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Abandone imediatamente regiões costeiras e zonas ribeirinhas em direção a um local mais seguro, como um terreno elevado."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Mantenha a calma e procure abrigo nas proximidades."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Teste de mensagens de emergência"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM não permitido"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM não ativado"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a373b45..05af326 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Saia imediatamente de regiões costeiras e áreas ribeirinhas e vá para um lugar mais seguro, como terrenos elevados."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Fique calmo e procure um abrigo por perto."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Teste de mensagens de emergência"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM não permitido"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM não aprovisionado"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 83afac8..795b71b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1803,8 +1803,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Părăsiți imediat zonele de coastă și din apropierea râurilor și îndreptați-vă spre un loc mai sigur, cum ar fi o zonă aflată la înălțime."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Păstrați-vă calmul și căutați un adăpost în apropiere."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testarea mesajelor de urgență"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Răspundeți"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Cardul SIM nu este permis"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Cardul SIM nu este activat"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 913c93b..d22022d 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1837,8 +1837,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Немедленно эвакуируйтесь из прибрежной зоны в более высокое место."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Сохраняйте спокойствие и поищите укрытие поблизости."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тестовое экстренное сообщение"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Ответить"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Использование SIM-карты запрещено"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-карта не активирована"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 641bd40..0292f82 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1771,8 +1771,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"මුහුදු බඩ ප්‍රදේශ සහ ගංඉවුරු ප්‍රදේශ සිට ඉහළ ප්‍රදේශයක් වැනි ආරක්‍ෂිත තැනකට දැන්ම යන්න."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"සන්සුන්ව ඉන්න සහ අවට ඇති නවාතැන් පහසුකම් බලන්න."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"හදිසි පණිවිඩ පරීක්ෂණය"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"පිළිතුරු දෙන්න"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM එක සඳහා ඉඩ නොදේ"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM එක සක්‍රීය කර නොමැත"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d68ebc4..4c22ae7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1837,8 +1837,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Okamžite začnite evakuáciu z prímorských a nábrežných oblastí na bezpečnejšie miesto, napríklad do vyššie položených regiónov."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachovajte pokoj a vyhľadajte úkryt v okolí."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test tiesňových správ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odpovedať"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karta je zakázaná"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karta nie je k dispozícii"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 381154f..c31c8a4 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evakuohu menjëherë nga rajonet bregdetare dhe zonat pranë lumenjve drejt një vendi më të sigurt, si për shembull në një terren të ngritur."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Qëndro i qetë dhe kërko strehim në afërsi."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testim për mesazhet e urgjencës"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Përgjigju"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Karta SIM nuk lejohet"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Karta SIM nuk është dhënë"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 704869d..02dddb8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1803,8 +1803,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Одмах се склоните из приобалних региона и области поред река на неко безбедније место, на пример, на неко узвишење."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Останите мирни и потражите склониште у околини."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тестирање порука у хитним случајевима"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Одговори"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM картица није дозвољена"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM картица није подешена"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 7339480..b1a1351 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Utrym kust- och flodområden omedelbart och förflytta er till en säkrare plats, till exempel ett högt beläget område."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Håll dig lugn och sök skydd i närheten."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test för nödmeddelanden"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Svara"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-kort tillåts inte"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-kort tillhandahålls inte"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index a855231..2eb1720 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1767,8 +1767,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ondoka mara moja kwenye maeneo ya ufuo na mito ili uende kwenye sehemu salama kama vile milimani."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tulia na utafute hifadhi ya karibu."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Jaribio la ujumbe wa dharura"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Jibu"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM imekataliwa"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM haikubaliwi"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 45ac5c5..714602f 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"கடலோரப் பகுதிகளிலும் ஆற்றங்கரைகளிலும் வசிப்பவர்கள் உடனடியாகப் பாதுகாப்பான இடத்திற்குச் (மேட்டுப்பகுதி) செல்லவும்."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"பதட்டப்படாதீர்கள், அருகில் ஏதேனும் பாதுகாப்பான இடம் உள்ளதா எனப் பாருங்கள்."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"அவசரக் காலச் செய்திகளுக்கான சோதனை"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"பதிலளிக்கும்"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"சிம் அனுமதிக்கப்படவில்லை"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"சிம் அமைக்கப்படவில்லை"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 3078330..92fba6e 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"వెంటనే తీర ప్రాంతాలు మరియు నదీ పరీవాహక ప్రాంతాలను ఖాళీ చేసి మెట్ట ప్రాంతాలకు తరలి వెళ్లండి."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ప్రశాంతంగా ఉండండి మరియు దగ్గర్లో తలదాచుకోండి."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"అత్యవసర సందేశాల పరీక్ష"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ప్రత్యుత్తరం పంపండి"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM అనుమతించబడదు"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM సక్రియం కాలేదు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 9be0d4a..3c33686 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1618,7 +1618,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"ติดตั้งโดยผู้ดูแลระบบ"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"อัปเดตโดยผู้ดูแลระบบ"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"ลบโดยผู้ดูแลระบบ"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"เพื่อช่วยปรับปรุงอายุการใช้งานแบตเตอรี่ โหมดประหยัดแบตเตอรี่จะลดการทำงานของอุปกรณ์และจำกัดการสั่น บริการตำแหน่ง และข้อมูลแบ็กกราวด์ส่วนใหญ่ สำหรับอีเมล การรับส่งข้อความ และแอปอื่นๆ ที่ใช้การซิงค์จะไม่อัปเดตหากคุณไม่เปิดขึ้นมา\n\nโหมดประหยัดแบตเตอรี่จะปิดโดยอัตโนมัติขณะชาร์จอุปกรณ์"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"เพื่อช่วยยืดอายุการใช้งานแบตเตอรี่ โหมดประหยัดแบตเตอรี่จะลดการทำงานของอุปกรณ์และจำกัดการสั่น บริการตำแหน่ง และข้อมูลแบ็กกราวด์ส่วนใหญ่ สำหรับอีเมล การรับส่งข้อความ และแอปอื่นๆ ที่ใช้การซิงค์จะไม่อัปเดตหากคุณไม่เปิดขึ้นมา\n\nโหมดประหยัดแบตเตอรี่จะปิดโดยอัตโนมัติขณะชาร์จอุปกรณ์"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"เพื่อช่วยลดปริมาณการใช้อินเทอร์เน็ต โปรแกรมประหยัดอินเทอร์เน็ตจะช่วยป้องกันไม่ให้แอปบางส่วนส่งหรือรับข้อมูลเครือข่ายมือถือในพื้นหลัง แอปที่คุณกำลังใช้งานสามารถเข้าถึงข้อมูลเครือข่ายมือถือได้ แต่อาจไม่บ่อยเท่าเดิม ตัวอย่างเช่น ภาพต่างๆ จะไม่แสดงจนกว่าคุณจะแตะที่ภาพเหล่านั้น"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"เปิดการประหยัดอินเทอร์เน็ตไหม"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"เปิด"</string>
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"อพยพออกจากจากเขตชายฝั่งทะเลและบริเวณริมแม่น้ำไปยังสถานที่ที่ปลอดภัยกว่า เช่น ที่สูง โดยทันที"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"ทำใจให้สงบและหาที่กำบังในบริเวณใกล้เคียง"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"การทดสอบข้อความกรณีฉุกเฉิน"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"ตอบ"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"ไม่อนุญาตให้ใช้ซิม"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"ไม่มีการจัดสรรซิม"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index a85e2e5..2976911 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Umalis kaagad sa mga baybayin at pampang, at pumunta sa isang mas ligtas na lokasyon tulad ng isang mataas na lugar."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Manatiling kalmado at maghanap ng matutuluyan sa malapit."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Pagsubok sa mga mensaheng pang-emergency"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Tumugon"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"Hindi pinahihintulutan ang SIM"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"Hindi naprobisyon ang SIM"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 0e318e7..715a019 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1837,8 +1837,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Негайно евакуюйтеся з прибережних районів і територій поблизу річок у безпечніше місце, як-от на територію на підвищенні."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Не хвилюйтеся та знайдіть прихисток поблизу."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Перевірка екстрених повідомлень"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Відповісти"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM-карта заборонена"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM-карту не затверджено"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index da90d58..ca75369 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"ساحلی خطوں اور دریائی کناروں کے علاقوں کو فوری طور پر خالی کر کے اونچے ٹیلے جیسے کسی زیادہ محفوظ مقام پر چلے جائیں۔"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"پُرسکون رہیں اور قریبی پناہ حاصل کریں۔"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"ایمرجنسی پیغامات کی جانچ"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"جواب دیں"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"‏SIM کی اجازت نہیں ہے"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"‏SIM فراہم کردہ نہیں ہے"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index d93a0f5..e262893 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1770,8 +1770,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Qirg‘oq va daryo bo‘ylaridan yuqori tepalik kabi xavfsiz joylarga darhol evakuatsiya qiling."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Tinchlaning va yaqin-atrofdan boshpana qidiring."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Favqulodda holatlar uchun sinov xabarlari"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Javob berish"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karta ishlatish taqiqlangan"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karta yo‘q"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4e93512..73a65b7 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Ngay lập tức sơ tán khỏi các vùng ven biển và khu vực ven sông để tới một nơi an toàn hơn như vùng đất cao."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hãy bình tĩnh và tìm kiếm nơi trú ẩn gần đó."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Kiểm tra thông báo khẩn cấp"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Trả lời"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM không được cho phép"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM không được cấp phép"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index e9a19ca..57798ee 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"請立即從沿海和河岸地區撤離,前往高地等較安全的地點。"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"請保持冷靜,並尋找附近的避難所。"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"緊急訊息測試"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"回覆"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"不允許使用 SIM 卡"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"無法識別 SIM 卡"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a040520e..39564ea 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"請立即從沿海與河岸地區撤離,前往高地這類較安全的地點。"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"請保持冷靜並尋找附近的避難地點。"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"緊急訊息測試"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"回覆"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"不受允許的 SIM 卡"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"未佈建的 SIM 卡"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 5ab61a6..8518096 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1769,8 +1769,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Phuma ngokushesha kusukela kuzifunda ezingasolwandle nasezindaweni zemifula uye endaweni ephephile efana nendawo ephakeme."</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Hlala ubeke umoya phansi uphinde ufune ukukhuselwa eduze."</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Ukuhlolwa kwemilayezo yesimo esiphuthumayo"</string>
-    <!-- no translation found for notification_reply_button_accessibility (3621714652387814344) -->
-    <skip />
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Phendula"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="7729819349669603406">"I-SIM ayivunyelwe"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"I-SIM ayinikezelwe"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 79bb109..dd840b0 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3619,6 +3619,13 @@
         <attr name="name" />
     </declare-styleable>
 
+    <!-- Specify one or more <code>t3tPmm-filter</code> elements inside a
+         <code>host-nfcf-service</code> element to specify a LF_T3T_PMM -->
+    <declare-styleable name="T3tPmmFilter">
+        <attr name="name" />
+
+    </declare-styleable>
+
     <declare-styleable name="ActionMenuItemView">
         <attr name="minWidth" />
     </declare-styleable>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 01b8e15..33f69b4 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1051,6 +1051,22 @@
          <p>The default value of this attribute is <code>false</code>. -->
     <attr name="isolatedSplits" format="boolean" />
 
+    <!-- The classname of the classloader used to load the application's classes
+         from its APK. The APK in question can either be the 'base' APK or any
+         of the application's 'split' APKs if it's using a feature split.
+
+         <p>
+         The supported values for this attribute are
+         <code>dalvik.system.PathClassLoader</code> and
+         <code>dalvik.system.DelegateLastClassLoader</code>. If unspecified,
+         the default value of this attribute is <code>dalvik.system.PathClassLoader</code>.
+
+         If an unknown classloader is provided, a PackageParserException with cause
+         <code>PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED</code> will be
+         thrown and the app will not be installed.
+         -->
+    <attr name="classLoader" format="string" />
+
     <!-- If set to <code>true</code>, indicates to the platform that this APK is
          a 'feature' split and that it implicitly depends on the base APK. This distinguishes
          this split APK from a 'configuration' split, which provides resource overrides
@@ -1485,6 +1501,9 @@
             <enum name="productivity" value="7" />
         </attr>
 
+        <!-- Declares the kind of classloader this application's classes must be loaded with -->
+        <attr name="classLoader" />
+
     </declare-styleable>
     <!-- The <code>permission</code> tag declares a security permission that can be
          used to control access from other packages to specific components or
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 802f027..ba5af2f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1332,7 +1332,7 @@
          permission.
          [This is only used if config_enableUpdateableTimeZoneRules and
          config_timeZoneRulesUpdateTrackingEnabled are true.] -->
-    <string name="config_timeZoneRulesUpdaterPackage" translateable="false"></string>
+    <string name="config_timeZoneRulesUpdaterPackage" translateable="false">com.android.timezone.updater</string>
 
     <!-- The package of the time zone rules data application. Expected to be configured
          by OEMs to reference their own priv-app APK package.
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index fa33d56..9f9c883 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -533,6 +533,8 @@
     <dimen name="content_rect_bottom_clip_allowance">20dp</dimen>
 
     <dimen name="chooser_grid_padding">0dp</dimen>
+    <!-- Spacing around the background change frome service to non-service -->
+    <dimen name="chooser_service_spacing">8dp</dimen>
 
     <item type="dimen" name="aerr_padding_list_top">15dp</item>
     <item type="dimen" name="aerr_padding_list_bottom">8dp</item>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2a4881d..634d79a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2845,6 +2845,7 @@
     <public-group type="attr" first-id="0x01010569">
         <public name="showWhenLocked"/>
         <public name="turnScreenOn"/>
+        <public name="classLoader" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d9ce7fb..6d6064f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3053,4 +3053,5 @@
   <java-symbol type="string" name="popup_window_default_title" />
   <java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
   <java-symbol type="layout" name="shutdown_dialog" />
+  <java-symbol type="dimen" name="chooser_service_spacing" />
 </resources>
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index ac1ac19..5457713 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.util.NotificationColorUtil.satisfiesTextContrast;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
@@ -26,8 +27,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.NotificationColorUtil;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -44,9 +43,51 @@
     }
 
     @Test
+    public void testColorizedByPermission() {
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_CAN_COLORIZE, true)
+                .setColorized(true)
+                .build();
+        assertTrue(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_CAN_COLORIZE, true)
+                .build();
+        assertFalse(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_CAN_COLORIZE, false)
+                .setColorized(true)
+                .build();
+        assertFalse(n.isColorized());
+    }
+
+    @Test
+    public void testColorizedByForeground() {
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+                .setColorized(true)
+                .build();
+        assertTrue(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+                .build();
+        assertFalse(n.isColorized());
+
+        n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, false)
+                .setColorized(true)
+                .build();
+        assertFalse(n.isColorized());
+    }
+
+    @Test
     public void testColorSatisfiedWhenBgDarkTextDarker() {
         Notification.Builder builder = getMediaNotification();
-        builder.build();
+        Notification n = builder.build();
+
+        assertTrue(n.isColorized());
 
         // An initial guess where the foreground color is actually darker than an already dark bg
         int backgroundColor = 0xff585868;
@@ -58,6 +99,45 @@
         assertTrue(satisfiesTextContrast(secondaryTextColor, backgroundColor));
     }
 
+    @Test
+    public void testHasCompletedProgress_noProgress() {
+        Notification n = new Notification.Builder(mContext).build();
+
+        assertFalse(n.hasCompletedProgress());
+    }
+
+    @Test
+    public void testHasCompletedProgress_complete() {
+        Notification n = new Notification.Builder(mContext)
+                .setProgress(100, 100, true)
+                .build();
+        Notification n2 = new Notification.Builder(mContext)
+                .setProgress(10, 10, false)
+                .build();
+        assertTrue(n.hasCompletedProgress());
+        assertTrue(n2.hasCompletedProgress());
+    }
+
+    @Test
+    public void testHasCompletedProgress_notComplete() {
+        Notification n = new Notification.Builder(mContext)
+                .setProgress(100, 99, true)
+                .build();
+        Notification n2 = new Notification.Builder(mContext)
+                .setProgress(10, 4, false)
+                .build();
+        assertFalse(n.hasCompletedProgress());
+        assertFalse(n2.hasCompletedProgress());
+    }
+
+    @Test
+    public void testHasCompletedProgress_zeroMax() {
+        Notification n = new Notification.Builder(mContext)
+                .setProgress(0, 0, true)
+                .build();
+        assertFalse(n.hasCompletedProgress());
+    }
+
     private Notification.Builder getMediaNotification() {
         MediaSession session = new MediaSession(mContext, "test");
         return new Notification.Builder(mContext, "color")
diff --git a/core/tests/coretests/src/android/net/SSLSessionCacheTest.java b/core/tests/coretests/src/android/net/SSLSessionCacheTest.java
index ec130e0..11d066b 100644
--- a/core/tests/coretests/src/android/net/SSLSessionCacheTest.java
+++ b/core/tests/coretests/src/android/net/SSLSessionCacheTest.java
@@ -44,12 +44,9 @@
 
         try {
             SSLSessionCache.install(new SSLSessionCache(mock), ctx);
-            clientCtx.getSession("www.foogle.com", 443);
-            Mockito.verify(mock).getSessionData(Mockito.anyString(), Mockito.anyInt());
         } finally {
             // Restore cacheless behaviour.
             SSLSessionCache.install(null, ctx);
-            clientCtx.getSession("www.foogle.com", 443);
             Mockito.verifyNoMoreInteractions(mock);
         }
     }
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index b96bda1..5af2396 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -200,7 +200,7 @@
                     Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
                     Settings.Global.ERROR_LOGCAT_PREFIX,
                     Settings.Global.EUICC_PROVISIONED,
-                    Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
+                    Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
                     Settings.Global.FANCY_IME_ANIMATIONS,
                     Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
                     Settings.Global.FSTRIM_MANDATORY_INTERVAL,
@@ -418,6 +418,7 @@
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
+                 Settings.Secure.AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY,
                  Settings.Secure.BACKUP_AUTO_RESTORE,
                  Settings.Secure.BACKUP_ENABLED,
                  Settings.Secure.BACKUP_PROVISIONED,
@@ -464,11 +465,7 @@
                  Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
                  Settings.Secure.PAYMENT_SERVICE_SEARCH_URI,
                  Settings.Secure.PRINT_SERVICE_SEARCH_URI,
-                 Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, // Candidate?
-                 Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, // Candidate?
-                 Settings.Secure.SCREENSAVER_COMPONENTS,
                  Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, // Candidate?
-                 Settings.Secure.SCREENSAVER_ENABLED, // Candidate?
                  Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY,
                  Settings.Secure.SEARCH_MAX_RESULTS_PER_SOURCE,
                  Settings.Secure.SEARCH_MAX_RESULTS_TO_DISPLAY,
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index 4cc648d..472b3e2 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -363,14 +363,23 @@
     @Test
     public void testCharSequenceCreator() {
         Parcel p = Parcel.obtain();
-        TextUtils.writeToParcel(null, p, 0);
-        CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
-        assertNull("null CharSequence should generate null from parcel", text);
+        CharSequence text;
+        try {
+            TextUtils.writeToParcel(null, p, 0);
+            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
+            assertNull("null CharSequence should generate null from parcel", text);
+        } finally {
+            p.recycle();
+        }
         p = Parcel.obtain();
-        TextUtils.writeToParcel("test", p, 0);
-        p.setDataPosition(0);
-        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
-        assertEquals("conversion to/from parcel failed", "test", text);
+        try {
+            TextUtils.writeToParcel("test", p, 0);
+            p.setDataPosition(0);
+            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
+            assertEquals("conversion to/from parcel failed", "test", text);
+        } finally {
+            p.recycle();
+        }
     }
 
     @Test
@@ -378,10 +387,14 @@
         Parcel p;
         CharSequence text;
         p = Parcel.obtain();
-        TextUtils.writeToParcel(null, p, 0);
-        p.setDataPosition(0);
-        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
-        assertNull("null CharSequence should generate null from parcel", text);
+        try {
+            TextUtils.writeToParcel(null, p, 0);
+            p.setDataPosition(0);
+            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
+            assertNull("null CharSequence should generate null from parcel", text);
+        } finally {
+            p.recycle();
+        }
     }
 
     @Test
@@ -389,10 +402,14 @@
         Parcel p;
         CharSequence text;
         p = Parcel.obtain();
-        TextUtils.writeToParcel(new SpannableString("test"), p, 0);
-        p.setDataPosition(0);
-        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
-        assertEquals("conversion to/from parcel failed", "test", text.toString());
+        try {
+            TextUtils.writeToParcel(new SpannableString("test"), p, 0);
+            p.setDataPosition(0);
+            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
+            assertEquals("conversion to/from parcel failed", "test", text.toString());
+        } finally {
+            p.recycle();
+        }
     }
 
     @Test
@@ -400,10 +417,14 @@
         Parcel p;
         CharSequence text;
         p = Parcel.obtain();
-        TextUtils.writeToParcel("test", p, 0);
-        p.setDataPosition(0);
-        text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
-        assertEquals("conversion to/from parcel failed", "test", text.toString());
+        try {
+            TextUtils.writeToParcel("test", p, 0);
+            p.setDataPosition(0);
+            text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
+            assertEquals("conversion to/from parcel failed", "test", text.toString());
+        } finally {
+            p.recycle();
+        }
     }
 
     /**
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 19d2a31..85ea1ff 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -163,6 +163,8 @@
     <!-- This is a list of all the libraries available for application
          code to link against. -->
 
+    <library name="android.test.mock"
+            file="/system/framework/android.test.mock.jar" />
     <library name="android.test.runner"
             file="/system/framework/android.test.runner.jar" />
     <library name="javax.obex"
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 19cc7b3..a79376c 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -163,8 +163,8 @@
         <permission name="android.permission.UPDATE_DEVICE_STATS"/>
         <permission name="android.permission.UPDATE_LOCK"/>
         <permission name="android.permission.WRITE_APN_SETTINGS"/>
-        <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+        <permission name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
         <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
         <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
     </privapp-permissions>
diff --git a/libs/androidfw/include/androidfw/StringPiece.h b/libs/androidfw/include/androidfw/StringPiece.h
index a873d66..99b4245 100644
--- a/libs/androidfw/include/androidfw/StringPiece.h
+++ b/libs/androidfw/include/androidfw/StringPiece.h
@@ -37,6 +37,7 @@
  public:
   using const_iterator = const TChar*;
   using difference_type = size_t;
+  using size_type = size_t;
 
   // End of string marker.
   constexpr static const size_t npos = static_cast<size_t>(-1);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 92d53da6..113a477 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -202,6 +202,7 @@
         "PathTessellator.cpp",
         "PixelBuffer.cpp",
         "ProfileData.cpp",
+        "ProfileDataContainer.cpp",
         "ProfileRenderer.cpp",
         "Program.cpp",
         "ProgramCache.cpp",
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index f9671ed4..9d11828 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -65,11 +65,8 @@
 // and filter it out of the frame profile data
 static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync;
 
-JankTracker::JankTracker(const DisplayInfo& displayInfo) {
-    // By default this will use malloc memory. It may be moved later to ashmem
-    // if there is shared space for it and a request comes in to do that.
-    mData = new ProfileData;
-    reset();
+JankTracker::JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo) {
+    mGlobalData = globalData;
     nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / displayInfo.fps);
 #if USE_HWC2
     nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms);
@@ -89,60 +86,6 @@
     setFrameInterval(frameIntervalNanos);
 }
 
-JankTracker::~JankTracker() {
-    freeData();
-}
-
-void JankTracker::freeData() {
-    if (mIsMapped) {
-        munmap(mData, sizeof(ProfileData));
-    } else {
-        delete mData;
-    }
-    mIsMapped = false;
-    mData = nullptr;
-}
-
-void JankTracker::rotateStorage() {
-    // If we are mapped we want to stop using the ashmem backend and switch to malloc
-    // We are expecting a switchStorageToAshmem call to follow this, but it's not guaranteed
-    // If we aren't sitting on top of ashmem then just do a reset() as it's functionally
-    // equivalent do a free, malloc, reset.
-    if (mIsMapped) {
-        freeData();
-        mData = new ProfileData;
-    }
-    reset();
-}
-
-void JankTracker::switchStorageToAshmem(int ashmemfd) {
-    int regionSize = ashmem_get_size_region(ashmemfd);
-    if (regionSize < 0) {
-        int err = errno;
-        ALOGW("Failed to get ashmem region size from fd %d, err %d %s", ashmemfd, err, strerror(err));
-        return;
-    }
-    if (regionSize < static_cast<int>(sizeof(ProfileData))) {
-        ALOGW("Ashmem region is too small! Received %d, required %u",
-                regionSize, static_cast<unsigned int>(sizeof(ProfileData)));
-        return;
-    }
-    ProfileData* newData = reinterpret_cast<ProfileData*>(
-            mmap(NULL, sizeof(ProfileData), PROT_READ | PROT_WRITE,
-            MAP_SHARED, ashmemfd, 0));
-    if (newData == MAP_FAILED) {
-        int err = errno;
-        ALOGW("Failed to move profile data to ashmem fd %d, error = %d",
-                ashmemfd, err);
-        return;
-    }
-
-    newData->mergeWith(*mData);
-    freeData();
-    mData = newData;
-    mIsMapped = true;
-}
-
 void JankTracker::setFrameInterval(nsecs_t frameInterval) {
     mFrameInterval = frameInterval;
     mThresholds[kMissedVsync] = 1;
@@ -166,7 +109,7 @@
 
 }
 
-void JankTracker::addFrame(const FrameInfo& frame) {
+void JankTracker::finishFrame(const FrameInfo& frame) {
     // Fast-path for jank-free frames
     int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::FrameCompleted);
     if (mDequeueTimeForgiveness
@@ -187,6 +130,7 @@
     }
     LOG_ALWAYS_FATAL_IF(totalDuration <= 0, "Impossible totalDuration %" PRId64, totalDuration);
     mData->reportFrame(totalDuration);
+    (*mGlobalData)->reportFrame(totalDuration);
 
     // Keep the fast path as fast as possible.
     if (CC_LIKELY(totalDuration < mFrameInterval)) {
@@ -199,11 +143,13 @@
     }
 
     mData->reportJank();
+    (*mGlobalData)->reportJank();
 
     for (int i = 0; i < NUM_BUCKETS; i++) {
         int64_t delta = frame.duration(COMPARISONS[i].start, COMPARISONS[i].end);
         if (delta >= mThresholds[i] && delta < IGNORE_EXCEEDING) {
             mData->reportJankType((JankType) i);
+            (*mGlobalData)->reportJankType((JankType) i);
         }
     }
 }
@@ -228,8 +174,31 @@
     dprintf(fd, "\n");
 }
 
+void JankTracker::dumpFrames(int fd) {
+    FILE* file = fdopen(fd, "a");
+    fprintf(file, "\n\n---PROFILEDATA---\n");
+    for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) {
+        fprintf(file, "%s", FrameInfoNames[i].c_str());
+        fprintf(file, ",");
+    }
+    for (size_t i = 0; i < mFrames.size(); i++) {
+        FrameInfo& frame = mFrames[i];
+        if (frame[FrameInfoIndex::SyncStart] == 0) {
+            continue;
+        }
+        fprintf(file, "\n");
+        for (int i = 0; i < static_cast<int>(FrameInfoIndex::NumIndexes); i++) {
+            fprintf(file, "%" PRId64 ",", frame[i]);
+        }
+    }
+    fprintf(file, "\n---PROFILEDATA---\n\n");
+    fflush(file);
+}
+
 void JankTracker::reset() {
+    mFrames.clear();
     mData->reset();
+    (*mGlobalData)->reset();
     sFrameStart = Properties::filterOutTestOverhead
             ? FrameInfoIndex::HandleInputStart
             : FrameInfoIndex::IntendedVsync;
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 2c567b3..e56c079 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -18,6 +18,7 @@
 
 #include "FrameInfo.h"
 #include "ProfileData.h"
+#include "ProfileDataContainer.h"
 #include "renderthread/TimeLord.h"
 #include "utils/RingBuffer.h"
 
@@ -48,26 +49,25 @@
 // TODO: Replace DrawProfiler with this
 class JankTracker {
 public:
-    explicit JankTracker(const DisplayInfo& displayInfo);
-    ~JankTracker();
+    explicit JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo);
 
     void setDescription(JankTrackerType type, const std::string&& name) {
         mDescription.type = type;
         mDescription.name = name;
     }
 
-    void addFrame(const FrameInfo& frame);
+    FrameInfo* startFrame() { return &mFrames.next(); }
+    void finishFrame(const FrameInfo& frame);
 
-    void dump(int fd) { dumpData(fd, &mDescription, mData); }
+    void dumpStats(int fd) { dumpData(fd, &mDescription, mData.get()); }
+    void dumpFrames(int fd);
     void reset();
 
-    void rotateStorage();
-    void switchStorageToAshmem(int ashmemfd);
-
-    uint32_t findPercentile(int p) { return mData->findPercentile(p); }
+    // Exposed for FrameInfoVisualizer
+    // TODO: Figure out a better way to handle this
+    RingBuffer<FrameInfo, 120>& frames() { return mFrames; }
 
 private:
-    void freeData();
     void setFrameInterval(nsecs_t frameIntervalNanos);
 
     static void dumpData(int fd, const ProfileDataDescription* description, const ProfileData* data);
@@ -82,9 +82,12 @@
     // This is only used if we are in pipelined mode and are using HWC2,
     // otherwise it's 0.
     nsecs_t mDequeueTimeForgiveness = 0;
-    ProfileData* mData;
-    bool mIsMapped = false;
+    ProfileDataContainer mData;
+    ProfileDataContainer* mGlobalData;
     ProfileDataDescription mDescription;
+
+    // Ring buffer large enough for 2 seconds worth of frames
+    RingBuffer<FrameInfo, 120> mFrames;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index 19d5d9d..e798edf 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -238,6 +238,7 @@
         // TODO: We should convert to linear space when the target is RGBA16F
         glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
                 type, bitmap->getPixels());
+        bitmap->notifyPixelsChanged();
     }
 
     // Cleanup
diff --git a/libs/hwui/ProfileDataContainer.cpp b/libs/hwui/ProfileDataContainer.cpp
new file mode 100644
index 0000000..cbf3eb3
--- /dev/null
+++ b/libs/hwui/ProfileDataContainer.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ProfileDataContainer.h"
+
+#include <log/log.h>
+#include <cutils/ashmem.h>
+
+#include <sys/mman.h>
+
+namespace android {
+namespace uirenderer {
+
+void ProfileDataContainer::freeData() {
+    if (mIsMapped) {
+        munmap(mData, sizeof(ProfileData));
+    } else {
+        delete mData;
+    }
+    mIsMapped = false;
+    mData = nullptr;
+}
+
+void ProfileDataContainer::rotateStorage() {
+    // If we are mapped we want to stop using the ashmem backend and switch to malloc
+    // We are expecting a switchStorageToAshmem call to follow this, but it's not guaranteed
+    // If we aren't sitting on top of ashmem then just do a reset() as it's functionally
+    // equivalent do a free, malloc, reset.
+    if (mIsMapped) {
+        freeData();
+        mData = new ProfileData;
+    }
+    mData->reset();
+}
+
+void ProfileDataContainer::switchStorageToAshmem(int ashmemfd) {
+    int regionSize = ashmem_get_size_region(ashmemfd);
+    if (regionSize < 0) {
+        int err = errno;
+        ALOGW("Failed to get ashmem region size from fd %d, err %d %s", ashmemfd, err, strerror(err));
+        return;
+    }
+    if (regionSize < static_cast<int>(sizeof(ProfileData))) {
+        ALOGW("Ashmem region is too small! Received %d, required %u",
+                regionSize, static_cast<unsigned int>(sizeof(ProfileData)));
+        return;
+    }
+    ProfileData* newData = reinterpret_cast<ProfileData*>(
+            mmap(NULL, sizeof(ProfileData), PROT_READ | PROT_WRITE,
+                    MAP_SHARED, ashmemfd, 0));
+    if (newData == MAP_FAILED) {
+        int err = errno;
+        ALOGW("Failed to move profile data to ashmem fd %d, error = %d",
+                ashmemfd, err);
+        return;
+    }
+
+    newData->mergeWith(*mData);
+    freeData();
+    mData = newData;
+    mIsMapped = true;
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
\ No newline at end of file
diff --git a/libs/hwui/ProfileDataContainer.h b/libs/hwui/ProfileDataContainer.h
new file mode 100644
index 0000000..d2de241
--- /dev/null
+++ b/libs/hwui/ProfileDataContainer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "ProfileData.h"
+#include "utils/Macros.h"
+
+namespace android {
+namespace uirenderer {
+
+class ProfileDataContainer {
+    PREVENT_COPY_AND_ASSIGN(ProfileDataContainer);
+public:
+    explicit ProfileDataContainer() {}
+
+    ~ProfileDataContainer() { freeData(); }
+
+    void rotateStorage();
+    void switchStorageToAshmem(int ashmemfd);
+
+    ProfileData* get() { return mData; }
+    ProfileData* operator->() { return mData; }
+
+private:
+    void freeData();
+
+    // By default this will use malloc memory. It may be moved later to ashmem
+    // if there is shared space for it and a request comes in to do that.
+    ProfileData* mData = new ProfileData;
+    bool mIsMapped = false;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
\ No newline at end of file
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index 89697d7..e865b57 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -97,6 +97,7 @@
             image = scaledSurface->makeImageSnapshot();
 
             if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) {
+                bitmap->notifyPixelsChanged();
                 copyResult = CopyResult::Success;
             }
         }
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 7799248..5d7f594 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -142,8 +142,8 @@
         : mRenderThread(thread)
         , mOpaque(!translucent)
         , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
-        , mJankTracker(thread.mainDisplayInfo())
-        , mProfiler(mFrames)
+        , mJankTracker(&thread.globalProfileData(), thread.mainDisplayInfo())
+        , mProfiler(mJankTracker.frames())
         , mContentDrawBounds(0, 0, 0, 0)
         , mRenderPipeline(std::move(renderPipeline)) {
     rootRenderNode->makeRoot();
@@ -321,7 +321,7 @@
     // If the previous frame was dropped we don't need to hold onto it, so
     // just keep using the previous frame's structure instead
     if (!wasSkipped(mCurrentFrameInfo)) {
-        mCurrentFrameInfo = &mFrames.next();
+        mCurrentFrameInfo = mJankTracker.startFrame();
     }
     mCurrentFrameInfo->importUiThreadInfo(uiFrameInfo);
     mCurrentFrameInfo->set(FrameInfoIndex::SyncQueued) = syncQueued;
@@ -485,8 +485,7 @@
     }
 #endif
 
-    mJankTracker.addFrame(*mCurrentFrameInfo);
-    mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo);
+    mJankTracker.finishFrame(*mCurrentFrameInfo);
     if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) {
         mFrameMetricsReporter->reportFrameMetrics(mCurrentFrameInfo->data());
     }
@@ -625,30 +624,12 @@
 }
 
 void CanvasContext::dumpFrames(int fd) {
-    mJankTracker.dump(fd);
-    FILE* file = fdopen(fd, "a");
-    fprintf(file, "\n\n---PROFILEDATA---\n");
-    for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) {
-        fprintf(file, "%s", FrameInfoNames[i].c_str());
-        fprintf(file, ",");
-    }
-    for (size_t i = 0; i < mFrames.size(); i++) {
-        FrameInfo& frame = mFrames[i];
-        if (frame[FrameInfoIndex::SyncStart] == 0) {
-            continue;
-        }
-        fprintf(file, "\n");
-        for (int i = 0; i < static_cast<int>(FrameInfoIndex::NumIndexes); i++) {
-            fprintf(file, "%" PRId64 ",", frame[i]);
-        }
-    }
-    fprintf(file, "\n---PROFILEDATA---\n\n");
-    fflush(file);
+    mJankTracker.dumpStats(fd);
+    mJankTracker.dumpFrames(fd);
 }
 
 void CanvasContext::resetFrameStats() {
-    mFrames.clear();
-    mRenderThread.jankTracker().reset();
+    mJankTracker.reset();
 }
 
 void CanvasContext::setName(const std::string&& name) {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index b1f4050..aa6d2f3 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -29,7 +29,6 @@
 #include "RenderNode.h"
 #include "thread/Task.h"
 #include "thread/TaskProcessor.h"
-#include "utils/RingBuffer.h"
 #include "renderthread/RenderTask.h"
 #include "renderthread/RenderThread.h"
 
@@ -253,8 +252,6 @@
     std::vector< sp<RenderNode> > mRenderNodes;
 
     FrameInfo* mCurrentFrameInfo = nullptr;
-    // Ring buffer large enough for 2 seconds worth of frames
-    RingBuffer<FrameInfo, 120> mFrames;
     std::string mName;
     JankTracker mJankTracker;
     FrameInfoVisualizer mProfiler;
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index cc791f6..16d7736 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -79,6 +79,7 @@
     bool noConfigContext = false;
     bool pixelFormatFloat = false;
     bool glColorSpace = false;
+    bool scRGB = false;
 } EglExtensions;
 
 EglManager::EglManager(RenderThread& thread)
@@ -161,6 +162,11 @@
     EglExtensions.glColorSpace = extensions.has("EGL_KHR_gl_colorspace");
     EglExtensions.noConfigContext = extensions.has("EGL_KHR_no_config_context");
     EglExtensions.pixelFormatFloat = extensions.has("EGL_EXT_pixel_format_float");
+#ifdef ANDROID_ENABLE_LINEAR_BLENDING
+    EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb_linear");
+#else
+    EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
+#endif
 }
 
 bool EglManager::hasEglContext() {
@@ -249,7 +255,7 @@
 EGLSurface EglManager::createSurface(EGLNativeWindowType window, bool wideColorGamut) {
     initialize();
 
-    wideColorGamut = wideColorGamut && EglExtensions.glColorSpace
+    wideColorGamut = wideColorGamut && EglExtensions.glColorSpace && EglExtensions.scRGB
             && EglExtensions.pixelFormatFloat && EglExtensions.noConfigContext;
 
     // The color space we want to use depends on whether linear blending is turned
@@ -289,9 +295,7 @@
         }
 #else
         if (wideColorGamut) {
-            // TODO: this should be using scRGB-nl, not scRGB, we need an extension for this
-            // TODO: in the meantime SurfaceFlinger just assumes that scRGB is scRGB-nl
-            attribs[1] = EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT;
+            attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
         } else {
             attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
         }
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 80c2955..370cf52 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -427,12 +427,12 @@
     if (args->dumpFlags & DumpFlags::FrameStats) {
         args->context->dumpFrames(args->fd);
     }
+    if (args->dumpFlags & DumpFlags::JankStats) {
+        args->thread->globalProfileData()->dump(args->fd);
+    }
     if (args->dumpFlags & DumpFlags::Reset) {
         args->context->resetFrameStats();
     }
-    if (args->dumpFlags & DumpFlags::JankStats) {
-        args->thread->jankTracker().dump(args->fd);
-    }
     return nullptr;
 }
 
@@ -458,7 +458,7 @@
 
 CREATE_BRIDGE2(frameTimePercentile, RenderThread* thread, int percentile) {
     return reinterpret_cast<void*>(static_cast<uintptr_t>(
-        args->thread->jankTracker().findPercentile(args->percentile)));
+        args->thread->globalProfileData()->findPercentile(args->percentile)));
 }
 
 uint32_t RenderProxy::frameTimePercentile(int p) {
@@ -483,7 +483,7 @@
 }
 
 CREATE_BRIDGE2(setProcessStatsBuffer, RenderThread* thread, int fd) {
-    args->thread->jankTracker().switchStorageToAshmem(args->fd);
+    args->thread->globalProfileData().switchStorageToAshmem(args->fd);
     close(args->fd);
     return nullptr;
 }
@@ -497,7 +497,7 @@
 }
 
 CREATE_BRIDGE1(rotateProcessStatsBuffer, RenderThread* thread) {
-    args->thread->jankTracker().rotateStorage();
+    args->thread->globalProfileData().rotateStorage();
     return nullptr;
 }
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 13af2c4..72a428f 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -200,13 +200,12 @@
     initializeDisplayEventReceiver();
     mEglManager = new EglManager(*this);
     mRenderState = new RenderState(*this);
-    mJankTracker = new JankTracker(mDisplayInfo);
     mVkManager = new VulkanManager(*this);
     mCacheManager = new CacheManager(mDisplayInfo);
 }
 
 void RenderThread::dumpGraphicsMemory(int fd) {
-    jankTracker().dump(fd);
+    globalProfileData()->dump(fd);
 
     String8 cachesOutput;
     String8 pipeline;
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index d984257..bef47b3 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -97,7 +97,7 @@
     TimeLord& timeLord() { return mTimeLord; }
     RenderState& renderState() const { return *mRenderState; }
     EglManager& eglManager() const { return *mEglManager; }
-    JankTracker& jankTracker() { return *mJankTracker; }
+    ProfileDataContainer& globalProfileData() { return mGlobalProfileData; }
     Readback& readback();
 
     const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
@@ -160,7 +160,7 @@
     RenderState* mRenderState;
     EglManager* mEglManager;
 
-    JankTracker* mJankTracker = nullptr;
+    ProfileDataContainer mGlobalProfileData;
     Readback* mReadback = nullptr;
 
     sk_sp<GrContext> mGrContext;
diff --git a/libs/hwui/tests/common/LeakChecker.cpp b/libs/hwui/tests/common/LeakChecker.cpp
index d935382..fe38ec9 100644
--- a/libs/hwui/tests/common/LeakChecker.cpp
+++ b/libs/hwui/tests/common/LeakChecker.cpp
@@ -58,9 +58,8 @@
     if (merged.num_leaks) {
         cout << endl << "Leaked memory!" << endl;
         if (!merged.leaks[0].backtrace.num_frames) {
-            cout << "Re-run with 'setprop libc.debug.malloc.program hwui_unit_test'"
-                    << endl << "and 'setprop libc.debug.malloc.options backtrace=8'"
-                    << " to get backtraces" << endl;
+            cout << "Re-run with 'export LIBC_DEBUG_MALLOC_OPTIONS=backtrace' to get backtraces"
+                    << endl;
         }
         cout << merged.ToString(false);
     }
diff --git a/lowpan/Android.mk b/lowpan/Android.mk
index 9e9164f..0079958 100644
--- a/lowpan/Android.mk
+++ b/lowpan/Android.mk
@@ -28,4 +28,6 @@
 LOCAL_AIDL_INCLUDES += frameworks/base/core/java
 LOCAL_SRC_FILES += $(call all-Iaidl-files-under, java/android/net/lowpan)
 include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
 endif
diff --git a/lowpan/java/android/net/lowpan/ILowpanInterface.aidl b/lowpan/java/android/net/lowpan/ILowpanInterface.aidl
index 647fcc1..329e9fa 100644
--- a/lowpan/java/android/net/lowpan/ILowpanInterface.aidl
+++ b/lowpan/java/android/net/lowpan/ILowpanInterface.aidl
@@ -37,41 +37,79 @@
     //////////////////////////////////////////////////////////////////////////
     // Property Key Constants
 
+    /** Type: Boolean */
     const String KEY_INTERFACE_ENABLED      = "android.net.lowpan.property.INTERFACE_ENABLED";
+
+    /** Type: Boolean */
     const String KEY_INTERFACE_UP           = "android.net.lowpan.property.INTERFACE_UP";
+
+    /** Type: Boolean */
     const String KEY_INTERFACE_COMMISSIONED = "android.net.lowpan.property.INTERFACE_COMMISSIONED";
+
+    /** Type: Boolean */
     const String KEY_INTERFACE_CONNECTED    = "android.net.lowpan.property.INTERFACE_CONNECTED";
+
+    /** Type: String */
     const String KEY_INTERFACE_STATE        = "android.net.lowpan.property.INTERFACE_STATE";
 
+    /** Type: String */
     const String KEY_NETWORK_NAME             = "android.net.lowpan.property.NETWORK_NAME";
+
+    /** Type: Integer */
     const String KEY_NETWORK_TYPE             = "android.net.lowpan.property.NETWORK_TYPE";
+
+    /** Type: Integer */
     const String KEY_NETWORK_PANID            = "android.net.lowpan.property.NETWORK_PANID";
+
+    /** Type: byte[] */
     const String KEY_NETWORK_XPANID           = "android.net.lowpan.property.NETWORK_XPANID";
+
+    /** Type: String */
     const String KEY_NETWORK_ROLE             = "android.net.lowpan.property.NETWORK_ROLE";
+
+    /** Type: byte[] */
     const String KEY_NETWORK_MASTER_KEY       = "android.net.lowpan.property.NETWORK_MASTER_KEY";
+
+    /** Type: Integer */
     const String KEY_NETWORK_MASTER_KEY_INDEX
         = "android.net.lowpan.property.NETWORK_MASTER_KEY_INDEX";
 
+    /** Type: int[] */
     const String KEY_SUPPORTED_CHANNELS = "android.net.lowpan.property.SUPPORTED_CHANNELS";
+
+    /** Type: Integer */
     const String KEY_CHANNEL            = "android.net.lowpan.property.CHANNEL";
+
+    /** Type: int[] */
     const String KEY_CHANNEL_MASK       = "android.net.lowpan.property.CHANNEL_MASK";
+
+    /** Type: Integer */
     const String KEY_MAX_TX_POWER       = "android.net.lowpan.property.MAX_TX_POWER";
+
+    /** Type: Integer */
     const String KEY_RSSI               = "android.net.lowpan.property.RSSI";
+
+    /** Type: Integer */
     const String KEY_LQI                = "android.net.lowpan.property.LQI";
 
-    const String KEY_LINK_ADDRESS_ARRAY = "android.net.lowpan.property.LINK_ADDRESS_ARRAY";
-    const String KEY_ROUTE_INFO_ARRAY   = "android.net.lowpan.property.ROUTE_INFO_ARRAY";
-
+    /** Type: byte[] */
     const String KEY_BEACON_ADDRESS     = "android.net.lowpan.property.BEACON_ORIGIN_ADDRESS";
+
+    /** Type: Boolean */
     const String KEY_BEACON_CAN_ASSIST  = "android.net.lowpan.property.BEACON_CAN_ASSIST";
 
+    /** Type: String */
     const String DRIVER_VERSION         = "android.net.lowpan.property.DRIVER_VERSION";
+
+    /** Type: String */
     const String NCP_VERSION            = "android.net.lowpan.property.NCP_VERSION";
 
-    /** @hide */
+    /** Type: byte[]
+     * @hide */
     const String KEY_EXTENDED_ADDRESS = "android.net.lowpan.property.EXTENDED_ADDRESS";
 
-    /** @hide */
+    /** Type: byte[]
+     * @hide */
     const String KEY_MAC_ADDRESS      = "android.net.lowpan.property.MAC_ADDRESS";
 
     //////////////////////////////////////////////////////////////////////////
@@ -144,6 +182,9 @@
     void startEnergyScan(in Map properties, ILowpanEnergyScanCallback listener);
     oneway void stopEnergyScan();
 
+    String[] copyLinkAddresses();
+    IpPrefix[] copyLinkNetworks();
+
     void addOnMeshPrefix(in IpPrefix prefix, int flags);
     oneway void removeOnMeshPrefix(in IpPrefix prefix);
 
diff --git a/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl b/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl
index c99d732..0ae01a1 100644
--- a/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl
+++ b/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl
@@ -16,7 +16,15 @@
 
 package android.net.lowpan;
 
+import android.net.IpPrefix;
+
 /** {@hide} */
 interface ILowpanInterfaceListener {
     oneway void onPropertiesChanged(in Map properties);
+
+    oneway void onLinkNetworkAdded(in IpPrefix prefix);
+    oneway void onLinkNetworkRemoved(in IpPrefix prefix);
+
+    oneway void onLinkAddressAdded(in String address);
+    oneway void onLinkAddressRemoved(in String address);
 }
diff --git a/lowpan/java/android/net/lowpan/ILowpanManager.aidl b/lowpan/java/android/net/lowpan/ILowpanManager.aidl
index 5a8d7dc..326aa65 100644
--- a/lowpan/java/android/net/lowpan/ILowpanManager.aidl
+++ b/lowpan/java/android/net/lowpan/ILowpanManager.aidl
@@ -21,6 +21,7 @@
 /** {@hide} */
 interface ILowpanManager {
 
+    /* Keep this in sync with Context.LOWPAN_SERVICE */
     const String LOWPAN_SERVICE_NAME = "lowpan";
 
     ILowpanInterface getInterface(@utf8InCpp String name);
diff --git a/lowpan/java/android/net/lowpan/LowpanException.java b/lowpan/java/android/net/lowpan/LowpanException.java
index b43b2fe..5a1f729 100644
--- a/lowpan/java/android/net/lowpan/LowpanException.java
+++ b/lowpan/java/android/net/lowpan/LowpanException.java
@@ -16,8 +16,6 @@
 
 package android.net.lowpan;
 
-import android.os.DeadObjectException;
-import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.util.AndroidException;
 
@@ -49,92 +47,76 @@
     public static final int LOWPAN_JOIN_FAILED_AT_AUTH = 16;
     public static final int LOWPAN_FORM_FAILED_AT_SCAN = 17;
 
-    /**
-     * Convert ServiceSpecificExceptions and Binder RemoteExceptions from LoWPAN binder interfaces
-     * into the correct public exceptions.
-     *
-     * @hide
-     */
-    public static void throwAsPublicException(Throwable t) throws LowpanException {
-        if (t instanceof ServiceSpecificException) {
-            ServiceSpecificException e = (ServiceSpecificException) t;
-            int reason;
-            switch (e.errorCode) {
-                case ILowpanInterface.ERROR_INVALID_ARGUMENT:
-                case ILowpanInterface.ERROR_INVALID_TYPE:
-                case ILowpanInterface.ERROR_INVALID_VALUE:
-                    throw new IllegalArgumentException(e.getMessage(), e);
+    public static LowpanException rethrowAsLowpanException(ServiceSpecificException e)
+            throws LowpanException {
+        int reason;
+        switch (e.errorCode) {
+            case ILowpanInterface.ERROR_INVALID_ARGUMENT:
+            case ILowpanInterface.ERROR_INVALID_TYPE:
+            case ILowpanInterface.ERROR_INVALID_VALUE:
+                throw new IllegalArgumentException(e.getMessage(), e);
 
-                case ILowpanInterface.ERROR_PERMISSION_DENIED:
-                    throw new SecurityException(e.getMessage(), e);
+            case ILowpanInterface.ERROR_PERMISSION_DENIED:
+                throw new SecurityException(e.getMessage(), e);
 
-                case ILowpanInterface.ERROR_DISABLED:
-                    reason = LowpanException.LOWPAN_DISABLED;
-                    break;
+            case ILowpanInterface.ERROR_DISABLED:
+                reason = LowpanException.LOWPAN_DISABLED;
+                break;
 
-                case ILowpanInterface.ERROR_WRONG_STATE:
-                    reason = LowpanException.LOWPAN_WRONG_STATE;
-                    break;
+            case ILowpanInterface.ERROR_WRONG_STATE:
+                reason = LowpanException.LOWPAN_WRONG_STATE;
+                break;
 
-                case ILowpanInterface.ERROR_BUSY:
-                    reason = LowpanException.LOWPAN_BUSY;
-                    break;
+            case ILowpanInterface.ERROR_BUSY:
+                reason = LowpanException.LOWPAN_BUSY;
+                break;
 
-                case ILowpanInterface.ERROR_ALREADY:
-                    reason = LowpanException.LOWPAN_ALREADY;
-                    break;
+            case ILowpanInterface.ERROR_ALREADY:
+                reason = LowpanException.LOWPAN_ALREADY;
+                break;
 
-                case ILowpanInterface.ERROR_CANCELED:
-                    reason = LowpanException.LOWPAN_CANCELED;
-                    break;
+            case ILowpanInterface.ERROR_CANCELED:
+                reason = LowpanException.LOWPAN_CANCELED;
+                break;
 
-                case ILowpanInterface.ERROR_CREDENTIAL_NEEDED:
-                    reason = LowpanException.LOWPAN_CREDENTIAL_NEEDED;
-                    break;
+            case ILowpanInterface.ERROR_CREDENTIAL_NEEDED:
+                reason = LowpanException.LOWPAN_CREDENTIAL_NEEDED;
+                break;
 
-                case ILowpanInterface.ERROR_FEATURE_NOT_SUPPORTED:
-                    reason = LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED;
-                    break;
+            case ILowpanInterface.ERROR_FEATURE_NOT_SUPPORTED:
+                reason = LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED;
+                break;
 
-                case ILowpanInterface.ERROR_PROPERTY_NOT_FOUND:
-                    reason = LowpanException.LOWPAN_PROPERTY_NOT_FOUND;
-                    break;
+            case ILowpanInterface.ERROR_PROPERTY_NOT_FOUND:
+                reason = LowpanException.LOWPAN_PROPERTY_NOT_FOUND;
+                break;
 
-                case ILowpanInterface.ERROR_JOIN_FAILED_UNKNOWN:
-                    reason = LowpanException.LOWPAN_JOIN_FAILED_UNKNOWN;
-                    break;
+            case ILowpanInterface.ERROR_JOIN_FAILED_UNKNOWN:
+                reason = LowpanException.LOWPAN_JOIN_FAILED_UNKNOWN;
+                break;
 
-                case ILowpanInterface.ERROR_JOIN_FAILED_AT_SCAN:
-                    reason = LowpanException.LOWPAN_JOIN_FAILED_AT_SCAN;
-                    break;
+            case ILowpanInterface.ERROR_JOIN_FAILED_AT_SCAN:
+                reason = LowpanException.LOWPAN_JOIN_FAILED_AT_SCAN;
+                break;
 
-                case ILowpanInterface.ERROR_JOIN_FAILED_AT_AUTH:
-                    reason = LowpanException.LOWPAN_JOIN_FAILED_AT_AUTH;
-                    break;
+            case ILowpanInterface.ERROR_JOIN_FAILED_AT_AUTH:
+                reason = LowpanException.LOWPAN_JOIN_FAILED_AT_AUTH;
+                break;
 
-                case ILowpanInterface.ERROR_FORM_FAILED_AT_SCAN:
-                    reason = LowpanException.LOWPAN_FORM_FAILED_AT_SCAN;
-                    break;
+            case ILowpanInterface.ERROR_FORM_FAILED_AT_SCAN:
+                reason = LowpanException.LOWPAN_FORM_FAILED_AT_SCAN;
+                break;
 
-                case ILowpanInterface.ERROR_TIMEOUT:
-                case ILowpanInterface.ERROR_NCP_PROBLEM:
-                    reason = LowpanException.LOWPAN_NCP_PROBLEM;
-                    break;
-                case ILowpanInterface.ERROR_UNSPECIFIED:
-                default:
-                    reason = LOWPAN_ERROR;
-                    break;
-            }
-            throw new LowpanException(reason, e.getMessage(), e);
-        } else if (t instanceof DeadObjectException) {
-            throw new LowpanException(LOWPAN_DEAD, t);
-        } else if (t instanceof RemoteException) {
-            throw new UnsupportedOperationException(
-                    "An unknown RemoteException was thrown" + " which should never happen.", t);
-        } else if (t instanceof RuntimeException) {
-            RuntimeException e = (RuntimeException) t;
-            throw e;
+            case ILowpanInterface.ERROR_TIMEOUT:
+            case ILowpanInterface.ERROR_NCP_PROBLEM:
+                reason = LowpanException.LOWPAN_NCP_PROBLEM;
+                break;
+            case ILowpanInterface.ERROR_UNSPECIFIED:
+            default:
+                reason = LOWPAN_ERROR;
+                break;
         }
+        throw new LowpanException(reason, e.getMessage(), e);
     }
 
     private final int mReason;
diff --git a/lowpan/java/android/net/lowpan/LowpanIdentity.java b/lowpan/java/android/net/lowpan/LowpanIdentity.java
index 9be45ef..2d36f7f 100644
--- a/lowpan/java/android/net/lowpan/LowpanIdentity.java
+++ b/lowpan/java/android/net/lowpan/LowpanIdentity.java
@@ -53,7 +53,7 @@
         }
 
         public Builder setXpanid(byte x[]) {
-            identity.mXpanid = x.clone();
+            identity.mXpanid = (x != null ? x.clone() : null);
             return this;
         }
 
@@ -115,7 +115,7 @@
     }
 
     public byte[] getXpanid() {
-        return mXpanid.clone();
+        return mXpanid != null ? mXpanid.clone() : null;
     }
 
     public int getPanid() {
diff --git a/lowpan/java/android/net/lowpan/LowpanInterface.java b/lowpan/java/android/net/lowpan/LowpanInterface.java
index 2bb4ecd..55bf399 100644
--- a/lowpan/java/android/net/lowpan/LowpanInterface.java
+++ b/lowpan/java/android/net/lowpan/LowpanInterface.java
@@ -18,9 +18,12 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.Context;
 import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.os.DeadObjectException;
 import android.os.Handler;
-import android.os.IBinder;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.util.Log;
@@ -188,60 +191,35 @@
         public void onPropertiesChanged(@NonNull Map properties) {}
     }
 
-    private ILowpanInterface mBinder;
+    private final ILowpanInterface mBinder;
+    private final Looper mLooper;
     private final HashMap<Integer, ILowpanInterfaceListener> mListenerMap = new HashMap<>();
 
-    /** Map between IBinder identity hashes and LowpanInstance objects. */
-    private static final HashMap<Integer, LowpanInterface> sInstanceMap = new HashMap<>();
+    /**
+     * Create a new LowpanInterface instance. Applications will almost always want to use {@link
+     * LowpanManager#getInterface LowpanManager.getInterface()} instead of this.
+     *
+     * @param context the application context
+     * @param service the Binder interface
+     * @param looper the Binder interface
+     * @hide
+     */
+    public LowpanInterface(Context context, ILowpanInterface service, Looper looper) {
+        /* We aren't currently using the context, but if we need
+         * it later on we can easily add it to the class.
+         */
 
-    private LowpanInterface(IBinder binder) {
-        mBinder = ILowpanInterface.Stub.asInterface(binder);
+        mBinder = service;
+        mLooper = looper;
     }
 
     /**
-     * Get the LowpanInterface object associated with this IBinder. Returns null if this IBinder
-     * does not implement the appropriate interface.
+     * Returns the ILowpanInterface object associated with this interface.
      *
      * @hide
      */
-    @NonNull
-    public static final LowpanInterface from(IBinder binder) {
-        Integer hashCode = Integer.valueOf(System.identityHashCode(binder));
-        LowpanInterface instance;
-
-        synchronized (sInstanceMap) {
-            instance = sInstanceMap.get(hashCode);
-
-            if (instance == null) {
-                instance = new LowpanInterface(binder);
-                sInstanceMap.put(hashCode, instance);
-            }
-        }
-
-        return instance;
-    }
-
-    /** {@hide} */
-    public static final LowpanInterface from(ILowpanInterface iface) {
-        return from(iface.asBinder());
-    }
-
-    /** {@hide} */
-    public static final LowpanInterface getInterfaceFromBinder(IBinder binder) {
-        return from(binder);
-    }
-
-    /**
-     * Returns the IBinder object associated with this interface.
-     *
-     * @hide
-     */
-    public IBinder getBinder() {
-        return mBinder.asBinder();
-    }
-
-    private static void throwAsPublicException(Throwable t) throws LowpanException {
-        LowpanException.throwAsPublicException(t);
+    public ILowpanInterface getService() {
+        return mBinder;
     }
 
     // Private Property Helpers
@@ -251,11 +229,10 @@
             mBinder.setProperties(properties);
 
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
-            Log.e(TAG, x.toString());
+            throw x.rethrowAsRuntimeException();
 
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -263,13 +240,13 @@
     Map<String, Object> getProperties(String keys[]) throws LowpanException {
         try {
             return mBinder.getProperties(keys);
+
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
-            Log.e(TAG, x.toString());
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
-        return new HashMap();
     }
 
     /** @hide */
@@ -294,13 +271,13 @@
     <T> String getPropertyAsString(LowpanProperty<T> key) throws LowpanException {
         try {
             return mBinder.getPropertyAsString(key.getName());
+
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
-            Log.e(TAG, x.toString());
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
-        return null;
     }
 
     int getPropertyAsInt(LowpanProperty<Integer> key) throws LowpanException {
@@ -332,10 +309,12 @@
             Map<String, Object> parameters = new HashMap();
             provision.addToMap(parameters);
             mBinder.form(parameters);
+
         } catch (RemoteException x) {
-            throwAsPublicException(x);
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -352,10 +331,12 @@
             Map<String, Object> parameters = new HashMap();
             provision.addToMap(parameters);
             mBinder.join(parameters);
+
         } catch (RemoteException x) {
-            throwAsPublicException(x);
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -386,10 +367,12 @@
     public void leave() throws LowpanException {
         try {
             mBinder.leave();
+
         } catch (RemoteException x) {
-            throwAsPublicException(x);
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -415,34 +398,26 @@
     public void reset() throws LowpanException {
         try {
             mBinder.reset();
+
         } catch (RemoteException x) {
-            throwAsPublicException(x);
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
     // Public Getters and Setters
 
-    /**
-     * Returns the name of this network interface.
-     *
-     * <p>Will return empty string if this interface is no longer viable.
-     */
+    /** Returns the name of this network interface. */
     @NonNull
     public String getName() {
         try {
             return mBinder.getName();
+
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
-            // when fetching the name.
-            Log.e(TAG, x.toString());
-        } catch (ServiceSpecificException x) {
-            // Catch and ignore all service-specific exceptions
-            // when fetching the name.
-            Log.e(TAG, x.toString());
+            throw x.rethrowAsRuntimeException();
         }
-        return "";
     }
 
     /**
@@ -640,58 +615,77 @@
     public void registerCallback(@NonNull Callback cb, @Nullable Handler handler) {
         ILowpanInterfaceListener.Stub listenerBinder =
                 new ILowpanInterfaceListener.Stub() {
-                    public void onPropertiesChanged(Map properties) {
+                    private Handler mHandler;
+
+                    {
+                        if (handler != null) {
+                            mHandler = handler;
+                        } else if (mLooper != null) {
+                            mHandler = new Handler(mLooper);
+                        } else {
+                            mHandler = new Handler();
+                        }
+                    }
+
+                    @Override public void onPropertiesChanged(Map properties) {
                         Runnable runnable =
-                                new Runnable() {
-                                    @Override
-                                    public void run() {
-                                        for (String key : (Set<String>) properties.keySet()) {
-                                            Object value = properties.get(key);
-                                            switch (key) {
-                                                case ILowpanInterface.KEY_INTERFACE_ENABLED:
-                                                    cb.onEnabledChanged(
-                                                            ((Boolean) value).booleanValue());
-                                                    break;
-                                                case ILowpanInterface.KEY_INTERFACE_UP:
-                                                    cb.onUpChanged(
-                                                            ((Boolean) value).booleanValue());
-                                                    break;
-                                                case ILowpanInterface.KEY_INTERFACE_CONNECTED:
-                                                    cb.onConnectedChanged(
-                                                            ((Boolean) value).booleanValue());
-                                                    break;
-                                                case ILowpanInterface.KEY_INTERFACE_STATE:
-                                                    cb.onStateChanged((String) value);
-                                                    break;
-                                                case ILowpanInterface.KEY_NETWORK_NAME:
-                                                case ILowpanInterface.KEY_NETWORK_PANID:
-                                                case ILowpanInterface.KEY_NETWORK_XPANID:
-                                                case ILowpanInterface.KEY_CHANNEL:
-                                                    cb.onLowpanIdentityChanged(getLowpanIdentity());
-                                                    break;
-                                                case ILowpanInterface.KEY_NETWORK_ROLE:
-                                                    cb.onRoleChanged(value.toString());
-                                                    break;
-                                            }
+                                () -> {
+                                    for (String key : (Set<String>) properties.keySet()) {
+                                        Object value = properties.get(key);
+                                        switch (key) {
+                                            case ILowpanInterface.KEY_INTERFACE_ENABLED:
+                                                cb.onEnabledChanged(
+                                                        ((Boolean) value).booleanValue());
+                                                break;
+                                            case ILowpanInterface.KEY_INTERFACE_UP:
+                                                cb.onUpChanged(((Boolean) value).booleanValue());
+                                                break;
+                                            case ILowpanInterface.KEY_INTERFACE_CONNECTED:
+                                                cb.onConnectedChanged(
+                                                        ((Boolean) value).booleanValue());
+                                                break;
+                                            case ILowpanInterface.KEY_INTERFACE_STATE:
+                                                cb.onStateChanged((String) value);
+                                                break;
+                                            case ILowpanInterface.KEY_NETWORK_NAME:
+                                            case ILowpanInterface.KEY_NETWORK_PANID:
+                                            case ILowpanInterface.KEY_NETWORK_XPANID:
+                                            case ILowpanInterface.KEY_CHANNEL:
+                                                cb.onLowpanIdentityChanged(getLowpanIdentity());
+                                                break;
+                                            case ILowpanInterface.KEY_NETWORK_ROLE:
+                                                cb.onRoleChanged(value.toString());
+                                                break;
                                         }
-                                        cb.onPropertiesChanged(properties);
                                     }
+                                    cb.onPropertiesChanged(properties);
                                 };
 
-                        if (handler != null) {
-                            handler.post(runnable);
-                        } else {
-                            runnable.run();
-                        }
+                        mHandler.post(runnable);
+                    }
+
+                    @Override public void onLinkNetworkAdded(IpPrefix prefix) {
+                        // Support for this event isn't yet implemented.
+                    }
+
+                    @Override public void onLinkNetworkRemoved(IpPrefix prefix) {
+                        // Support for this event isn't yet implemented.
+                    }
+
+                    @Override public void onLinkAddressAdded(String address) {
+                        // Support for this event isn't yet implemented.
+                    }
+
+                    @Override public void onLinkAddressRemoved(String address) {
+                        // Support for this event isn't yet implemented.
                     }
                 };
         try {
             mBinder.addListener(listenerBinder);
         } catch (RemoteException x) {
-            // Log and ignore. If this happens, this interface
-            // is likely dead anyway.
-            Log.e(TAG, x.toString());
+            throw x.rethrowAsRuntimeException();
         }
+
         synchronized (mListenerMap) {
             mListenerMap.put(System.identityHashCode(cb), listenerBinder);
         }
@@ -728,9 +722,11 @@
 
                 try {
                     mBinder.removeListener(listenerBinder);
+                } catch (DeadObjectException x) {
+                    // We ignore a dead object exception because that
+                    // pretty clearly means our callback isn't registered.
                 } catch (RemoteException x) {
-                    // Catch and ignore all binder exceptions
-                    Log.e(TAG, x.toString());
+                    throw x.rethrowAsRuntimeException();
                 }
             }
         }
@@ -752,6 +748,46 @@
     // Route Management
 
     /**
+     * Makes a copy of the internal list of LinkAddresses.
+     *
+     * @hide
+     */
+    public LinkAddress[] copyLinkAddresses() throws LowpanException {
+        try {
+            String[] linkAddressStrings = mBinder.copyLinkAddresses();
+            LinkAddress[] ret = new LinkAddress[linkAddressStrings.length];
+            int i = 0;
+            for (String str : linkAddressStrings) {
+                ret[i++] = new LinkAddress(str);
+            }
+            return ret;
+
+        } catch (RemoteException x) {
+            throw x.rethrowAsRuntimeException();
+
+        } catch (ServiceSpecificException x) {
+            throw LowpanException.rethrowAsLowpanException(x);
+        }
+    }
+
+    /**
+     * Makes a copy of the internal list of networks reachable on via this link.
+     *
+     * @hide
+     */
+    public IpPrefix[] copyLinkNetworks() throws LowpanException {
+        try {
+            return mBinder.copyLinkNetworks();
+
+        } catch (RemoteException x) {
+            throw x.rethrowAsRuntimeException();
+
+        } catch (ServiceSpecificException x) {
+            throw LowpanException.rethrowAsLowpanException(x);
+        }
+    }
+
+    /**
      * Advertise the given IP prefix as an on-mesh prefix.
      *
      * @hide
@@ -759,10 +795,12 @@
     public void addOnMeshPrefix(IpPrefix prefix, int flags) throws LowpanException {
         try {
             mBinder.addOnMeshPrefix(prefix, flags);
+
         } catch (RemoteException x) {
-            throwAsPublicException(x);
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -775,9 +813,10 @@
     public void removeOnMeshPrefix(IpPrefix prefix) {
         try {
             mBinder.removeOnMeshPrefix(prefix);
+
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
-            Log.e(TAG, x.toString());
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
             // Catch and ignore all service exceptions
             Log.e(TAG, x.toString());
@@ -793,10 +832,12 @@
     public void addExternalRoute(IpPrefix prefix, int flags) throws LowpanException {
         try {
             mBinder.addExternalRoute(prefix, flags);
+
         } catch (RemoteException x) {
-            throwAsPublicException(x);
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -808,9 +849,10 @@
     public void removeExternalRoute(IpPrefix prefix) {
         try {
             mBinder.removeExternalRoute(prefix);
+
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
-            Log.e(TAG, x.toString());
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
             // Catch and ignore all service exceptions
             Log.e(TAG, x.toString());
diff --git a/lowpan/java/android/net/lowpan/LowpanManager.java b/lowpan/java/android/net/lowpan/LowpanManager.java
index ecdda49..2d974ee 100644
--- a/lowpan/java/android/net/lowpan/LowpanManager.java
+++ b/lowpan/java/android/net/lowpan/LowpanManager.java
@@ -19,14 +19,15 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.util.AndroidException;
-import android.util.Log;
+import java.lang.ref.WeakReference;
 import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
 
 /**
  * Manager object for looking up LoWPAN interfaces.
@@ -45,72 +46,119 @@
         public void onInterfaceRemoved(LowpanInterface lowpanInterface) {}
     }
 
-    private Context mContext;
-    private ILowpanManager mManager;
-    private HashMap<Integer, ILowpanManagerListener> mListenerMap = new HashMap<>();
+    private final Map<Integer, ILowpanManagerListener> mListenerMap = new HashMap<>();
+    private final Map<String, LowpanInterface> mInterfaceCache = new HashMap<>();
 
-    private static LowpanManager sSingletonInstance;
+    /* This is a WeakHashMap because we don't want to hold onto
+     * a strong reference to ILowpanInterface, so that it can be
+     * garbage collected if it isn't being used anymore. Since
+     * the value class holds onto this specific ILowpanInterface,
+     * we also need to have a weak reference to the value.
+     * This design pattern allows us to skip removal of items
+     * from this Map without leaking memory.
+     */
+    private final Map<ILowpanInterface, WeakReference<LowpanInterface>> mBinderCache =
+            new WeakHashMap<>();
+
+    private final ILowpanManager mService;
+    private final Context mContext;
+    private final Looper mLooper;
 
     // Static Methods
 
-    /** Returns a reference to the LowpanManager object, allocating it if necessary. */
-    public static LowpanManager getManager() {
-        return from(null);
+    public static LowpanManager from(Context context) {
+        return (LowpanManager) context.getSystemService(Context.LOWPAN_SERVICE);
     }
 
-    public static LowpanManager from(Context context) {
-        // TODO: Actually get this from the context!
+    /** @hide */
+    public static LowpanManager getManager() {
+        IBinder binder = ServiceManager.getService(Context.LOWPAN_SERVICE);
 
-        if (sSingletonInstance == null) {
-            sSingletonInstance = new LowpanManager();
+        if (binder != null) {
+            ILowpanManager service = ILowpanManager.Stub.asInterface(binder);
+            return new LowpanManager(service);
         }
-        return sSingletonInstance;
+
+        return null;
     }
 
     // Constructors
 
-    /**
-     * Private LowpanManager constructor. Since we are a singleton, we do not allow external
-     * construction.
-     */
-    private LowpanManager() {}
-
-    // Private Methods
-
-    /**
-     * Returns a reference to the ILowpanManager interface, provided by the LoWPAN Manager Service.
-     */
-    @Nullable
-    private synchronized ILowpanManager getILowpanManager() {
-        // Use a local reference of this object for thread safety.
-        ILowpanManager manager = mManager;
-
-        if (manager == null) {
-            IBinder serviceBinder =
-                    new ServiceManager().getService(ILowpanManager.LOWPAN_SERVICE_NAME);
-
-            manager = ILowpanManager.Stub.asInterface(serviceBinder);
-
-            mManager = manager;
-
-            // Add any listeners
-            synchronized (mListenerMap) {
-                for (ILowpanManagerListener listener : mListenerMap.values()) {
-                    try {
-                        manager.addListener(listener);
-
-                    } catch (RemoteException x) {
-                        // Consider any failure here as implying the manager is defunct
-                        mManager = null;
-                        manager = null;
-                    }
-                }
-            }
-        }
-        return manager;
+    LowpanManager(ILowpanManager service) {
+        mService = service;
+        mContext = null;
+        mLooper = null;
     }
 
-    // Public Methods
+    /**
+     * Create a new LowpanManager instance. Applications will almost always want to use {@link
+     * android.content.Context#getSystemService Context.getSystemService()} to retrieve the standard
+     * {@link android.content.Context#LOWPAN_SERVICE Context.LOWPAN_SERVICE}.
+     *
+     * @param context the application context
+     * @param service the Binder interface
+     * @param looper the default Looper to run callbacks on
+     * @hide - hide this because it takes in a parameter of type ILowpanManager, which is a system
+     *     private class.
+     */
+    public LowpanManager(Context context, ILowpanManager service, Looper looper) {
+        mContext = context;
+        mService = service;
+        mLooper = looper;
+    }
+
+    /** @hide */
+    @Nullable
+    public LowpanInterface getInterface(@NonNull ILowpanInterface ifaceService) {
+        LowpanInterface iface = null;
+
+        try {
+            synchronized (mBinderCache) {
+                if (mBinderCache.containsKey(ifaceService)) {
+                    iface = mBinderCache.get(ifaceService).get();
+                }
+
+                if (iface == null) {
+                    String ifaceName = ifaceService.getName();
+
+                    iface = new LowpanInterface(mContext, ifaceService, mLooper);
+
+                    synchronized (mInterfaceCache) {
+                        mInterfaceCache.put(iface.getName(), iface);
+                    }
+
+                    mBinderCache.put(ifaceService, new WeakReference(iface));
+
+                    /* Make sure we remove the object from the
+                     * interface cache if the associated service
+                     * dies.
+                     */
+                    ifaceService
+                            .asBinder()
+                            .linkToDeath(
+                                    new IBinder.DeathRecipient() {
+                                        @Override
+                                        public void binderDied() {
+                                            synchronized (mInterfaceCache) {
+                                                LowpanInterface iface =
+                                                        mInterfaceCache.get(ifaceName);
+
+                                                if ((iface != null)
+                                                        && (iface.getService() == ifaceService)) {
+                                                    mInterfaceCache.remove(ifaceName);
+                                                }
+                                            }
+                                        }
+                                    },
+                                    0);
+                }
+            }
+        } catch (RemoteException x) {
+            throw x.rethrowAsRuntimeException();
+        }
+
+        return iface;
+    }
 
     /**
      * Returns a reference to the requested LowpanInterface object. If the given interface doesn't
@@ -118,27 +166,32 @@
      */
     @Nullable
     public LowpanInterface getInterface(@NonNull String name) {
-        LowpanInterface ret = null;
-        ILowpanManager manager = getILowpanManager();
+        LowpanInterface iface = null;
 
-        // Maximum number of tries is two. We should only try
-        // more than once if our manager has died or there
-        // was some sort of AIDL buffer full event.
-        for (int i = 0; i < 2 && manager != null; i++) {
-            try {
-                ILowpanInterface iface = manager.getInterface(name);
-                if (iface != null) {
-                    ret = LowpanInterface.getInterfaceFromBinder(iface.asBinder());
+        try {
+            /* This synchronized block covers both branches of the enclosed
+             * if() statement in order to avoid a race condition. Two threads
+             * calling getInterface() with the same name would race to create
+             * the associated LowpanInterface object, creating two of them.
+             * Having the whole block be synchronized avoids that race.
+             */
+            synchronized (mInterfaceCache) {
+                if (mInterfaceCache.containsKey(name)) {
+                    iface = mInterfaceCache.get(name);
+
+                } else {
+                    ILowpanInterface ifaceService = mService.getInterface(name);
+
+                    if (ifaceService != null) {
+                        iface = getInterface(ifaceService);
+                    }
                 }
-                break;
-            } catch (RemoteException x) {
-                // In all of the cases when we get this exception, we reconnect and try again
-                mManager = null;
-                manager = getILowpanManager();
             }
+        } catch (RemoteException x) {
+            throw x.rethrowFromSystemServer();
         }
 
-        return ret;
+        return iface;
     }
 
     /**
@@ -160,23 +213,11 @@
      */
     @NonNull
     public String[] getInterfaceList() {
-        ILowpanManager manager = getILowpanManager();
-
-        // Maximum number of tries is two. We should only try
-        // more than once if our manager has died or there
-        // was some sort of AIDL buffer full event.
-        for (int i = 0; i < 2 && manager != null; i++) {
-            try {
-                return manager.getInterfaceList();
-            } catch (RemoteException x) {
-                // In all of the cases when we get this exception, we reconnect and try again
-                mManager = null;
-                manager = getILowpanManager();
-            }
+        try {
+            return mService.getInterfaceList();
+        } catch (RemoteException x) {
+            throw x.rethrowFromSystemServer();
         }
-
-        // Return empty list if we have no service.
-        return new String[0];
     }
 
     /**
@@ -189,55 +230,52 @@
             throws LowpanException {
         ILowpanManagerListener.Stub listenerBinder =
                 new ILowpanManagerListener.Stub() {
-                    public void onInterfaceAdded(ILowpanInterface lowpanInterface) {
-                        Runnable runnable =
-                                new Runnable() {
-                                    @Override
-                                    public void run() {
-                                        cb.onInterfaceAdded(
-                                                LowpanInterface.getInterfaceFromBinder(
-                                                        lowpanInterface.asBinder()));
-                                    }
-                                };
+                    private Handler mHandler;
 
+                    {
                         if (handler != null) {
-                            handler.post(runnable);
+                            mHandler = handler;
+                        } else if (mLooper != null) {
+                            mHandler = new Handler(mLooper);
                         } else {
-                            runnable.run();
+                            mHandler = new Handler();
                         }
                     }
 
-                    public void onInterfaceRemoved(ILowpanInterface lowpanInterface) {
+                    @Override
+                    public void onInterfaceAdded(ILowpanInterface ifaceService) {
                         Runnable runnable =
-                                new Runnable() {
-                                    @Override
-                                    public void run() {
-                                        cb.onInterfaceRemoved(
-                                                LowpanInterface.getInterfaceFromBinder(
-                                                        lowpanInterface.asBinder()));
+                                () -> {
+                                    LowpanInterface iface = getInterface(ifaceService);
+
+                                    if (iface != null) {
+                                        cb.onInterfaceAdded(iface);
                                     }
                                 };
 
-                        if (handler != null) {
-                            handler.post(runnable);
-                        } else {
-                            runnable.run();
-                        }
+                        mHandler.post(runnable);
+                    }
+
+                    @Override
+                    public void onInterfaceRemoved(ILowpanInterface ifaceService) {
+                        Runnable runnable =
+                                () -> {
+                                    LowpanInterface iface = getInterface(ifaceService);
+
+                                    if (iface != null) {
+                                        cb.onInterfaceRemoved(iface);
+                                    }
+                                };
+
+                        mHandler.post(runnable);
                     }
                 };
-        ILowpanManager manager = getILowpanManager();
-        if (manager != null) {
-            try {
-                manager.addListener(listenerBinder);
-            } catch (DeadObjectException x) {
-                mManager = null;
-                // Tickle the ILowpanManager instance, which might
-                // get us added back.
-                getILowpanManager();
-            } catch (Throwable x) {
-                LowpanException.throwAsPublicException(x);
-            }
+        try {
+            mService.addListener(listenerBinder);
+        } catch (RemoteException x) {
+            throw x.rethrowFromSystemServer();
         }
+
         synchronized (mListenerMap) {
             mListenerMap.put(Integer.valueOf(System.identityHashCode(cb)), listenerBinder);
         }
@@ -253,20 +291,23 @@
      *
      * @hide
      */
-    public void unregisterCallback(@NonNull Callback cb) throws AndroidException {
+    public void unregisterCallback(@NonNull Callback cb) {
         Integer hashCode = Integer.valueOf(System.identityHashCode(cb));
-        ILowpanManagerListener listenerBinder = mListenerMap.get(hashCode);
+        ILowpanManagerListener listenerBinder = null;
+
+        synchronized (mListenerMap) {
+            listenerBinder = mListenerMap.get(hashCode);
+            mListenerMap.remove(hashCode);
+        }
+
         if (listenerBinder != null) {
-            synchronized (mListenerMap) {
-                mListenerMap.remove(hashCode);
+            try {
+                mService.removeListener(listenerBinder);
+            } catch (RemoteException x) {
+                throw x.rethrowFromSystemServer();
             }
-            if (getILowpanManager() != null) {
-                try {
-                    mManager.removeListener(listenerBinder);
-                } catch (DeadObjectException x) {
-                    mManager = null;
-                }
-            }
+        } else {
+            throw new RuntimeException("Attempt to unregister an unknown callback");
         }
     }
 }
diff --git a/lowpan/java/android/net/lowpan/LowpanProperties.java b/lowpan/java/android/net/lowpan/LowpanProperties.java
index 0d5acc2..f835260 100644
--- a/lowpan/java/android/net/lowpan/LowpanProperties.java
+++ b/lowpan/java/android/net/lowpan/LowpanProperties.java
@@ -16,9 +16,8 @@
 
 package android.net.lowpan;
 
+import android.net.IpPrefix;
 import android.net.LinkAddress;
-import android.net.RouteInfo;
-import java.util.List;
 
 /** {@hide} */
 public final class LowpanProperties {
@@ -77,14 +76,6 @@
     public static final LowpanProperty<String> KEY_NCP_VERSION =
             new LowpanStandardProperty("android.net.lowpan.property.NCP_VERSION", String.class);
 
-    public static final LowpanProperty<List<LinkAddress>> KEY_LINK_ADDRESS_ARRAY =
-            new LowpanStandardProperty(
-                    "android.net.lowpan.property.LINK_ADDRESS_ARRAY", LinkAddress[].class);
-
-    public static final LowpanProperty<List<RouteInfo>> KEY_ROUTE_INFO_ARRAY =
-            new LowpanStandardProperty(
-                    "android.net.lowpan.property.ROUTE_INFO_ARRAY", RouteInfo[].class);
-
     /** @hide */
     public static final LowpanProperty<byte[]> KEY_EXTENDED_ADDRESS =
             new LowpanStandardProperty(
diff --git a/lowpan/java/android/net/lowpan/LowpanScanner.java b/lowpan/java/android/net/lowpan/LowpanScanner.java
index e0df55d9..b0557ee 100644
--- a/lowpan/java/android/net/lowpan/LowpanScanner.java
+++ b/lowpan/java/android/net/lowpan/LowpanScanner.java
@@ -226,8 +226,12 @@
 
         try {
             mBinder.startNetScan(map, binderListener);
-        } catch (ServiceSpecificException | RemoteException x) {
-            LowpanException.throwAsPublicException(x);
+
+        } catch (RemoteException x) {
+            throw x.rethrowAsRuntimeException();
+
+        } catch (ServiceSpecificException x) {
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -239,8 +243,11 @@
     public void stopNetScan() {
         try {
             mBinder.stopNetScan();
+
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
+            throw x.rethrowAsRuntimeException();
+
+        } catch (ServiceSpecificException x) {
             Log.e(TAG, x.toString());
         }
     }
@@ -303,10 +310,12 @@
 
         try {
             mBinder.startEnergyScan(map, binderListener);
+
         } catch (RemoteException x) {
-            LowpanException.throwAsPublicException(x);
+            throw x.rethrowAsRuntimeException();
+
         } catch (ServiceSpecificException x) {
-            LowpanException.throwAsPublicException(x);
+            throw LowpanException.rethrowAsLowpanException(x);
         }
     }
 
@@ -318,8 +327,11 @@
     public void stopEnergyScan() {
         try {
             mBinder.stopEnergyScan();
+
         } catch (RemoteException x) {
-            // Catch and ignore all binder exceptions
+            throw x.rethrowAsRuntimeException();
+
+        } catch (ServiceSpecificException x) {
             Log.e(TAG, x.toString());
         }
     }
diff --git a/lowpan/tests/Android.mk b/lowpan/tests/Android.mk
new file mode 100644
index 0000000..bb0a944
--- /dev/null
+++ b/lowpan/tests/Android.mk
@@ -0,0 +1,65 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# Make test APK
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+# This list is generated from the java source files in this module
+# The list is a comma separated list of class names with * matching zero or more characters.
+# Example:
+#   Input files: src/com/android/server/lowpan/Test.java src/com/android/server/lowpan/AnotherTest.java
+#   Generated exclude list: com.android.server.lowpan.Test*,com.android.server.lowpan.AnotherTest*
+
+# Filter all src files to just java files
+local_java_files := $(filter %.java,$(LOCAL_SRC_FILES))
+# Transform java file names into full class names.
+# This only works if the class name matches the file name and the directory structure
+# matches the package.
+local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files)))
+# Utility variables to allow replacing a space with a comma
+comma:= ,
+empty:=
+space:= $(empty) $(empty)
+# Convert class name list to jacoco exclude list
+# This appends a * to all classes and replace the space separators with commas.
+# These patterns will match all classes in this module and their inner classes.
+jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes)))
+
+jacoco_include := android.net.lowpan.*
+
+LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include)
+LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	android-support-test \
+	guava \
+	mockito-target-minus-junit4 \
+	frameworks-base-testutils \
+
+LOCAL_JAVA_LIBRARIES := \
+	android.test.runner \
+
+LOCAL_PACKAGE_NAME := FrameworksLowpanApiTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+LOCAL_CERTIFICATE := platform
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_PACKAGE)
diff --git a/lowpan/tests/AndroidManifest.xml b/lowpan/tests/AndroidManifest.xml
new file mode 100644
index 0000000..a216214
--- /dev/null
+++ b/lowpan/tests/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2017 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
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.net.lowpan.test">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:label="LowpanTestDummyLabel"
+                  android:name="LowpanTestDummyName">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.net.lowpan.test"
+        android:label="Frameworks LoWPAN API Tests">
+    </instrumentation>
+
+</manifest>
diff --git a/packages/SystemUI/colorextraction/tests/AndroidTest.xml b/lowpan/tests/AndroidTest.xml
similarity index 78%
rename from packages/SystemUI/colorextraction/tests/AndroidTest.xml
rename to lowpan/tests/AndroidTest.xml
index ee9ace4..72ad050 100644
--- a/packages/SystemUI/colorextraction/tests/AndroidTest.xml
+++ b/lowpan/tests/AndroidTest.xml
@@ -13,15 +13,15 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Runs Tests for ColorExtractor.">
+<configuration description="Runs Frameworks LoWPAN API Tests.">
     <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="ColorExtractorTests.apk" />
+        <option name="test-file-name" value="FrameworksLowpanApiTests.apk" />
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
-    <option name="test-tag" value="SystemUITests" />
+    <option name="test-tag" value="FrameworksLowpanApiTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.systemui.tests" />
+        <option name="package" value="android.net.lowpan.test" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
 </configuration>
diff --git a/lowpan/tests/README.md b/lowpan/tests/README.md
new file mode 100644
index 0000000..d0eed95
--- /dev/null
+++ b/lowpan/tests/README.md
@@ -0,0 +1,50 @@
+# LoWPAN Unit Tests
+This package contains unit tests for the android LoWPAN framework System APIs based on the
+[Android Testing Support Library](http://developer.android.com/tools/testing-support-library/index.html).
+The test cases are built using the [JUnit](http://junit.org/) and [Mockito](http://mockito.org/)
+libraries.
+
+## Running Tests
+The easiest way to run tests is simply run
+
+```
+frameworks/base/lowpan/tests/runtests.sh
+```
+
+`runtests.sh` will build the test project and all of its dependencies and push the APK to the
+connected device. It will then run the tests on the device.
+
+To pick up changes in framework/base, you will need to:
+1. rebuild the framework library 'make -j32'
+2. sync over the updated library to the device 'adb sync'
+3. restart framework on the device 'adb shell stop' then 'adb shell start'
+
+To enable syncing data to the device for first time after clean reflash:
+1. adb disable-verity
+2. adb reboot
+3. adb remount
+
+See below for a few example of options to limit which tests are run.
+See the
+[AndroidJUnitRunner Documentation](https://developer.android.com/reference/android/support/test/runner/AndroidJUnitRunner.html)
+for more details on the supported options.
+
+```
+runtests.sh -e package android.net.lowpan
+runtests.sh -e class android.net.lowpan.LowpanManagerTest
+```
+
+If you manually build and push the test APK to the device you can run tests using
+
+```
+adb shell am instrument -w 'android.net.wifi.test/android.support.test.runner.AndroidJUnitRunner'
+```
+
+## Adding Tests
+Tests can be added by adding classes to the src directory. JUnit4 style test cases can
+be written by simply annotating test methods with `org.junit.Test`.
+
+## Debugging Tests
+If you are trying to debug why tests are not doing what you expected, you can add android log
+statements and use logcat to view them. The beginning and end of every tests is automatically logged
+with the tag `TestRunner`.
diff --git a/lowpan/tests/runtests.sh b/lowpan/tests/runtests.sh
new file mode 100755
index 0000000..040f4f0
--- /dev/null
+++ b/lowpan/tests/runtests.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+  echo "You need to source and lunch before you can use this script"
+  exit 1
+fi
+
+echo "Running tests"
+
+set -e # fail early
+
+echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/base/lowpan/tests"
+# NOTE Don't actually run the command above since this shell doesn't inherit functions from the
+#      caller.
+make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-frameworks-base-lowpan-tests
+
+set -x # print commands
+
+adb root
+adb wait-for-device
+
+adb install -r -g "$OUT/data/app/FrameworksLowpanApiTests/FrameworksLowpanApiTests.apk"
+
+adb shell am instrument -w "$@" 'android.net.lowpan.test/android.support.test.runner.AndroidJUnitRunner'
diff --git a/lowpan/tests/src/android/net/lowpan/LowpanInterfaceTest.java b/lowpan/tests/src/android/net/lowpan/LowpanInterfaceTest.java
new file mode 100644
index 0000000..455ee08
--- /dev/null
+++ b/lowpan/tests/src/android/net/lowpan/LowpanInterfaceTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 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.net.lowpan;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.*;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.test.TestLooper;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import java.util.Map;
+import java.util.HashMap;
+
+/** Unit tests for android.net.lowpan.LowpanInterface. */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LowpanInterfaceTest {
+    private static final String TEST_PACKAGE_NAME = "TestPackage";
+
+    @Mock Context mContext;
+    @Mock ILowpanInterface mLowpanInterfaceService;
+    @Mock IBinder mLowpanInterfaceBinder;
+    @Mock ApplicationInfo mApplicationInfo;
+    @Mock IBinder mAppBinder;
+    @Mock LowpanInterface.Callback mLowpanInterfaceCallback;
+
+    private Handler mHandler;
+    private final TestLooper mTestLooper = new TestLooper();
+    private ILowpanInterfaceListener mInterfaceListener;
+    private LowpanInterface mLowpanInterface;
+    private Map<String, Object> mPropertyMap;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
+        when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(mLowpanInterfaceService.getName()).thenReturn("wpan0");
+        when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder);
+
+        mLowpanInterface = new LowpanInterface(mContext, mLowpanInterfaceService, mTestLooper.getLooper());
+    }
+
+    @Test
+    public void testStateChangedCallback() throws Exception {
+        // Register our callback
+        mLowpanInterface.registerCallback(mLowpanInterfaceCallback);
+
+        // Verify a listener was added
+        verify(mLowpanInterfaceService)
+                .addListener(
+                        argThat(
+                                listener -> {
+                                    mInterfaceListener = listener;
+                                    return listener instanceof ILowpanInterfaceListener;
+                                }));
+
+        // Build a changed property map
+        Map<String, Object> changedProperties = new HashMap<>();
+        LowpanProperties.KEY_INTERFACE_STATE.putInMap(changedProperties, LowpanInterface.STATE_OFFLINE);
+
+        // Change some properties
+        mInterfaceListener.onPropertiesChanged(changedProperties);
+        mTestLooper.dispatchAll();
+
+        // Verify that the property was changed
+        verify(mLowpanInterfaceCallback)
+                .onStateChanged(
+                        argThat(stateString -> stateString.equals(LowpanInterface.STATE_OFFLINE)));
+    }
+}
diff --git a/lowpan/tests/src/android/net/lowpan/LowpanManagerTest.java b/lowpan/tests/src/android/net/lowpan/LowpanManagerTest.java
new file mode 100644
index 0000000..481ad76
--- /dev/null
+++ b/lowpan/tests/src/android/net/lowpan/LowpanManagerTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 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.net.lowpan;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.*;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.test.TestLooper;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Unit tests for android.net.lowpan.LowpanManager. */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LowpanManagerTest {
+    private static final String TEST_PACKAGE_NAME = "TestPackage";
+
+    @Mock Context mContext;
+    @Mock ILowpanManager mLowpanService;
+    @Mock ILowpanInterface mLowpanInterfaceService;
+    @Mock IBinder mLowpanInterfaceBinder;
+    @Mock ApplicationInfo mApplicationInfo;
+    @Mock IBinder mAppBinder;
+    @Mock LowpanManager.Callback mLowpanManagerCallback;
+
+    private Handler mHandler;
+    private final TestLooper mTestLooper = new TestLooper();
+    private LowpanManager mLowpanManager;
+
+    private ILowpanManagerListener mManagerListener;
+    private LowpanInterface mLowpanInterface;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
+        when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+        mLowpanManager = new LowpanManager(mContext, mLowpanService, mTestLooper.getLooper());
+    }
+
+    @Test
+    public void testGetEmptyInterfaceList() throws Exception {
+        when(mLowpanService.getInterfaceList()).thenReturn(new String[0]);
+        assertTrue(mLowpanManager.getInterfaceList().length == 0);
+        assertTrue(mLowpanManager.getInterface() == null);
+    }
+
+    @Test
+    public void testGetInterfaceList() throws Exception {
+        when(mLowpanService.getInterfaceList()).thenReturn(new String[] {"wpan0"});
+        when(mLowpanService.getInterface("wpan0")).thenReturn(mLowpanInterfaceService);
+        when(mLowpanInterfaceService.getName()).thenReturn("wpan0");
+        when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder);
+        assertEquals(mLowpanManager.getInterfaceList().length, 1);
+
+        LowpanInterface iface = mLowpanManager.getInterface();
+        assertNotNull(iface);
+        assertEquals(iface.getName(), "wpan0");
+    }
+
+    @Test
+    public void testRegisterCallback() throws Exception {
+        when(mLowpanInterfaceService.getName()).thenReturn("wpan0");
+        when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder);
+
+        // Register our callback
+        mLowpanManager.registerCallback(mLowpanManagerCallback);
+
+        // Verify a listener was added
+        verify(mLowpanService)
+                .addListener(
+                        argThat(
+                                listener -> {
+                                    mManagerListener = listener;
+                                    return listener instanceof ILowpanManagerListener;
+                                }));
+
+        // Add an interface
+        mManagerListener.onInterfaceAdded(mLowpanInterfaceService);
+        mTestLooper.dispatchAll();
+
+        // Verify that the interface was added
+        verify(mLowpanManagerCallback)
+                .onInterfaceAdded(
+                        argThat(
+                                iface -> {
+                                    mLowpanInterface = iface;
+                                    return iface instanceof LowpanInterface;
+                                }));
+        verifyNoMoreInteractions(mLowpanManagerCallback);
+
+        // This check causes the test to fail with a weird error, but I'm not sure why.
+        assertEquals(mLowpanInterface.getService(), mLowpanInterfaceService);
+
+        // Verify that calling getInterface on the LowpanManager object will yield the same
+        // LowpanInterface object.
+        when(mLowpanService.getInterfaceList()).thenReturn(new String[] {"wpan0"});
+        when(mLowpanService.getInterface("wpan0")).thenReturn(mLowpanInterfaceService);
+        assertEquals(mLowpanManager.getInterface(), mLowpanInterface);
+
+        // Remove the service
+        mManagerListener.onInterfaceRemoved(mLowpanInterfaceService);
+        mTestLooper.dispatchAll();
+
+        // Verify that the interface was removed
+        verify(mLowpanManagerCallback).onInterfaceRemoved(mLowpanInterface);
+    }
+
+    @Test
+    public void testUnregisterCallback() throws Exception {
+        when(mLowpanInterfaceService.getName()).thenReturn("wpan0");
+        when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder);
+
+        // Register our callback
+        mLowpanManager.registerCallback(mLowpanManagerCallback);
+
+        // Verify a listener was added
+        verify(mLowpanService)
+                .addListener(
+                        argThat(
+                                listener -> {
+                                    mManagerListener = listener;
+                                    return listener instanceof ILowpanManagerListener;
+                                }));
+
+        // Add an interface
+        mManagerListener.onInterfaceAdded(mLowpanInterfaceService);
+        mTestLooper.dispatchAll();
+
+        // Verify that the interface was added
+        verify(mLowpanManagerCallback)
+                .onInterfaceAdded(
+                        argThat(
+                                iface -> {
+                                    mLowpanInterface = iface;
+                                    return iface instanceof LowpanInterface;
+                                }));
+        verifyNoMoreInteractions(mLowpanManagerCallback);
+
+        // Unregister our callback
+        mLowpanManager.unregisterCallback(mLowpanManagerCallback);
+
+        // Verify the listener was removed
+        verify(mLowpanService).removeListener(mManagerListener);
+
+        // Verify that the callback wasn't invoked.
+        verifyNoMoreInteractions(mLowpanManagerCallback);
+    }
+}
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 2b5ac5e..0a1de33 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -59,15 +59,4 @@
 
         int getRingerModeAffectedStreams(int streams);
     }
-
-    /**
-     * Disable or restore the ability to play audio for a given UID.
-     * When a UID isn't meant to be tracked anymore (e.g. client died), re-enable audio for this UID
-     * to prevent disabling audio for future UIDs that would reuse the same value.
-     * This operation is asynchronous.
-     * @param disable when true, prevents playback of audio streams from the given uid. If false,
-     *         restores the ability to play, or no-op if playback hadn't been disabled before.
-     * @param uid the client UID whose ability to play will be affected.
-     */
-    public abstract void disableAudioForUid(boolean disable, int uid);
 }
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index 61d642f..7e88c27 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -186,9 +186,9 @@
 
         /**
          * Declares whether this policy will grant and deny audio focus through
-         * the {@link AudioPolicy.AudioPolicyStatusListener}.
+         * the {@link AudioPolicy.AudioPolicyFocusListener}.
          * If set to {@code true}, it is mandatory to set an
-         * {@link AudioPolicy.AudioPolicyStatusListener} in order to successfully build
+         * {@link AudioPolicy.AudioPolicyFocusListener} in order to successfully build
          * an {@code AudioPolicy} instance.
          * @param enforce true if the policy will govern audio focus decisions.
          * @return the same Builder instance.
diff --git a/packages/CaptivePortalLogin/OWNERS b/packages/CaptivePortalLogin/OWNERS
new file mode 100644
index 0000000..fa26997
--- /dev/null
+++ b/packages/CaptivePortalLogin/OWNERS
@@ -0,0 +1,7 @@
+set noparent
+
+per-file Android.mk = build.master@android.com
+
+ek@google.com
+hugobenichi@google.com
+lorenzo@google.com
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 3dc170f..a7e1490 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -58,6 +58,7 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.Random;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 public class CaptivePortalLoginActivity extends Activity {
     private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
@@ -83,6 +84,8 @@
     private ConnectivityManager mCm;
     private boolean mLaunchBrowser = false;
     private MyWebViewClient mWebViewClient;
+    // Ensures that done() happens once exactly, handling concurrent callers with atomic operations.
+    private final AtomicBoolean isDone = new AtomicBoolean(false);
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -179,13 +182,13 @@
     }
 
     private void done(Result result) {
+        if (isDone.getAndSet(true)) {
+            // isDone was already true: done() already called
+            return;
+        }
         if (DBG) {
             Log.d(TAG, String.format("Result %s for %s", result.name(), mUrl.toString()));
         }
-        if (mNetworkCallback != null) {
-            mCm.unregisterNetworkCallback(mNetworkCallback);
-            mNetworkCallback = null;
-        }
         logMetricsEvent(result.metricsEvent);
         switch (result) {
             case DISMISSED:
@@ -245,8 +248,8 @@
     public void onDestroy() {
         super.onDestroy();
         if (mNetworkCallback != null) {
+            // mNetworkCallback is not null if mUrl is not null.
             mCm.unregisterNetworkCallback(mNetworkCallback);
-            mNetworkCallback = null;
         }
         if (mLaunchBrowser) {
             // Give time for this network to become default. After 500ms just proceed.
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index c1f03fd..ae8fc80 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -226,7 +226,8 @@
                 int httpResponseCode = 500;
                 int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
                 try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
+                    urlConnection = (HttpURLConnection) mNetwork.openConnection(
+                            new URL(mCm.getCaptivePortalServerUrl()));
                     urlConnection.setInstanceFollowRedirects(false);
                     urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
                     urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
@@ -234,6 +235,7 @@
                     urlConnection.getInputStream();
                     httpResponseCode = urlConnection.getResponseCode();
                 } catch (IOException e) {
+                    loge(e.getMessage());
                 } finally {
                     if (urlConnection != null) urlConnection.disconnect();
                     TrafficStats.setThreadStatsTag(oldTag);
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 9347877..3800e6f 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -213,27 +213,6 @@
         }
 
         @Override
-        public long calculateDirectorySize(String path) throws RemoteException {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
-            final File dir = Environment.maybeTranslateEmulatedPathToInternal(new File(path));
-            if (dir.exists() && dir.isDirectory()) {
-                final String targetPath = dir.getAbsolutePath();
-                return MeasurementUtils.measureDirectory(targetPath);
-            } else {
-                return 0L;
-            }
-        }
-
-        @Override
-        public long[] getFileSystemStats(String path) {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
-            final File file = new File(path);
-            return new long[] { file.getTotalSpace(), file.getUsableSpace() };
-        }
-
-        @Override
         public void clearDirectory(String path) throws RemoteException {
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
diff --git a/packages/SettingsLib/common.mk b/packages/SettingsLib/common.mk
index 0815534..46b66c4 100644
--- a/packages/SettingsLib/common.mk
+++ b/packages/SettingsLib/common.mk
@@ -20,13 +20,42 @@
     SettingsLib
 else
 LOCAL_RESOURCE_DIR += $(call my-dir)/res
+
+
+## Include transitive dependencies below
+
+# Include support-v7-appcompat, if not already included
+ifeq (,$(findstring android-support-v7-appcompat,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v7/appcompat/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.appcompat
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-appcompat
+endif
+
+# Include support-v7-recyclerview, if not already included
+ifeq (,$(findstring android-support-v7-recyclerview,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v7/recyclerview/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.recyclerview
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-recyclerview
+endif
+
+# Include android-support-v7-preference, if not already included
+ifeq (,$(findstring android-support-v7-preference,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v7/preference/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.preference
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-preference
+endif
+
+# Include android-support-v14-preference, if not already included
+ifeq (,$(findstring android-support-v14-preference,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v14/preference/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v14.preference
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v14-preference
+endif
+
 LOCAL_AAPT_FLAGS += --auto-add-overlay --extra-packages com.android.settingslib
+
 LOCAL_STATIC_JAVA_LIBRARIES += \
     android-support-annotations \
     android-support-v4 \
-    android-support-v7-appcompat \
-    android-support-v7-preference \
-    android-support-v7-recyclerview \
-    android-support-v14-preference \
     SettingsLib
 endif
diff --git a/packages/SettingsLib/res/drawable/ic_expand_more.xml b/packages/SettingsLib/res/drawable/ic_expand_more.xml
new file mode 100644
index 0000000..a8ff539
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_expand_more.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M16.59,8.59L12.0,13.17 7.41,8.59 6.0,10.0l6.0,6.0 6.0,-6.0z"/>
+
+</vector>
diff --git a/packages/SettingsLib/res/layout/preference_category_divider.xml b/packages/SettingsLib/res/layout/preference_category_divider.xml
new file mode 100644
index 0000000..6644eec
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_category_divider.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/two_target_divider"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:gravity="start|center_vertical"
+    android:orientation="horizontal">
+    <View
+        android:layout_height="1dp"
+        android:layout_width="match_parent"
+        android:background="?android:attr/dividerHorizontal" />
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml b/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml
new file mode 100644
index 0000000..70d0898
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 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.
+  -->
+
+<!-- Similar to preference_category_material_settings.xml, except that this always adds
+     a divider above category. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <include layout="@layout/preference_category_divider"/>
+    <include layout="@layout/preference_category_material_settings"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_dropdown_material_settings.xml b/packages/SettingsLib/res/layout/preference_dropdown_material_settings.xml
new file mode 100644
index 0000000..a0b8155
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_dropdown_material_settings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 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.
+  -->
+
+
+<!-- Based off frameworks/base/core/res/res/layout/preference_dropdown_material.xml
+     except that icon space in this layout is always reserved -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <Spinner
+        android:id="@+id/spinner"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/preference_no_icon_padding_start"
+        android:visibility="invisible" />
+
+    <include layout="@layout/preference_material"/>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_two_target.xml b/packages/SettingsLib/res/layout/preference_two_target.xml
index 7000940d..2309ec6 100644
--- a/packages/SettingsLib/res/layout/preference_two_target.xml
+++ b/packages/SettingsLib/res/layout/preference_two_target.xml
@@ -18,6 +18,7 @@
 <!-- Based off preference_material_settings.xml except that ripple on only on the left side. -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:minHeight="?android:attr/listPreferredItemHeightSmall"
@@ -50,8 +51,8 @@
                 android:id="@android:id/icon"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:maxWidth="48dp"
-                android:maxHeight="48dp" />
+                settings:maxWidth="48dp"
+                settings:maxHeight="48dp" />
         </LinearLayout>
 
         <RelativeLayout
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 7e50996..5d04cf6 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Gekoppel (geen media nie)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Gekoppel (geen boodskaptoegang nie)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Gekoppel (geen foon of media nie)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Gekoppel, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Gekoppel (geen foon nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Gekoppel (geen media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Gekoppel (geen foon en media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-oudio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Foonoproepe"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Lêeroordrag"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiewe Wi‑Fi-na-mobiel-oorhandiging"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Laat altyd Wi-Fi-swerfskanderings toe"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data is altyd aktief"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardewareversnelling vir verbinding"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiveer absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktiveer inband-luitoon"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-weergawe"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Laat skynliggings toe"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktiveer aansigkenmerkinspeksie"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hou mobiele data altyd aktief, selfs wanneer Wi‑Fi aktief is (vir vinnige netwerkwisseling)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gebruik hardewareversnelling vir verbinding indien beskikbaar"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Laat USB-ontfouting toe?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-ontfouting is net vir ontwikkelingsdoeleindes bedoel. Gebruik dit om data te kopieer tussen jou rekenaar en jou toestel, programme op jou toestel te installeer sonder kennisgewing en om loglêerdata te lees."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Herroep toegang tot USB-ontfouting vanaf alle rekenaars wat jy voorheen gemagtig het?"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 79cedfa..b42d26a 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ተያይዟል (ምንም ማህደረ መረጃ የለም)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ተገናኝቷል (ምንም የመልዕክት መዳረሻ የለም)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ተያይዟል (ምንም ስልክ ወይም ማህደረ መረጃ የለም)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ተገናኝቷል፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ተገናኝቷል (ምንም ስልክ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ተገናኝቷል (ምንም ማህደረ መረጃ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ተገናኝቷል (ምንም ስልክ ወይም ማህደረ መረጃ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"የማህደረ መረጃ ኦዲዮ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"የስልክ ጥሪዎች"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ፋይል ማስተላለፍ"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"አስገዳጅ ከWi‑Fi ወደ ሞባይል ማቀበል"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ሁልጊዜ የWi‑Fi ማንቀሳቀስ ቅኝቶችን ይፍቀዱ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"የሃርድዌር ማቀላጠፊያን በማስተሳሰር ላይ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ፍጹማዊ ድምፅን አሰናክል"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"የውስጠ-ሞገድ ማስጮህን አንቃ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"የብሉቱዝ AVRCP ስሪት"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"አስቂኝ ሥፍራዎችን ፍቀድ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"የእይታ አይነታ ምርመራን አንቃ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ምንም እንኳን Wi‑Fi ንቁ ቢሆንም የሞባይል ውሂብን ንቁ እንደሆነ አቆይ (ለፈጣን የአውታረ መረብ ቅይይር)።"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"የሃርድዌር ማቀላጠፊያን ማስተሳሰርን የሚገኝ ከሆነ ይጠቀሙ"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"የUSB ማረሚያ ይፈቀድ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"የUSB አድስ ለግንባታ አላማ ብቻ የታሰበ ነው። ከኮምፒዩተርህ ወደ መሳሪያህ ውሂብ ለመገልበጥ፣ መሣሪያህ ላይ ያለ ማሳወቂያ መተግበሪያዎችን መጫን፣ እና ማስታወሻ ውሂብ ማንበብ ለመጠቀም ይቻላል።"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"የዩ ኤስ ቢ ማረም መዳረሻ ከዚህ ቀደም ፍቃድ ከሰጧቸው ኮምፒውተሮች ላይ ይሻሩ?"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index d1b13a4..2ac6bb5 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"متصل (بجهاز غير الوسائط)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"تم الاتصال (يتعذر الدخول إلى الرسائل)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"متصل (بجهاز غير الهاتف أو الوسائط)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"الجهاز متّصل، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"الجهاز متّصل (من دون هاتف)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"الجهاز متّصل (من دون وسائط)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"الجهاز متّصل (من دون هاتف أو وسائط)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"الإعدادات الصوتية للوسائط"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"المكالمات الهاتفية"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"نقل الملف"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏تسليم Wi-Fi حاد إلى جوّال"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏السماح دائمًا بعمليات فحص Wi-Fi للتجوال"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"بيانات الجوّال نشطة دائمًا"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"تسريع الأجهزة للتوصيل"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"تعطيل مستوى الصوت المطلق"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"تمكين الرنين ضمن النطاق الأساسي"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏إصدار Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"السماح بمواقع وهمية"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"تمكين فحص سمة العرض"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏اجعل بيانات الجوّال نشطة دائمًا، حتى عندما يكون اتصال Wi‑Fi نشطًا (لتبديل الشبكة بسرعة)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"استخدام إعداد تسريع الأجهزة للتوصيل إن كان متاحًا"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏هل تريد السماح بتصحيح أخطاء USB؟"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏تم تصميم تصحيح أخطاء USB لأغراض التطوير فقط. يمكن استخدامه لنسخ البيانات بين الكمبيوتر والجهاز، وتثبيت التطبيقات على جهازك بدون تنبيه، وقراءة بيانات السجل."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏هل تريد إلغاء إمكانية الدخول إلى تصحيح أخطاء USB من جميع أجهزة الكمبيوتر التي تم التصريح لها سابقًا؟"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 95ea112..494ae00 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Qoşuludur (media yoxdur)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Qoşulu (mesaj girişi yoxdur)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Bağlantı yaradılıb (telefon və ya media deyil)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Qoşuldu, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Qoşuldu (telefondan başqa), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Qoşuldu (mediadan başqa), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Qoşuldu (telefon və ya mediadan başqa), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon zəngləri"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl transferi"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Möbül ötürücüyə aqressiv Wi‑Fi"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi axtarışlarına həmişə icazə verin"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil data həmişə aktiv"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Birləşmə üçün avadanlıq akselerasiyası"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mütləq səs həcmi deaktiv edin"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Diapazon daxili zəngi aktiv edin"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Versiya"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Sınaq yerləşmələrə icazə verin"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Atribut inspeksiyasına baxışa icazə verin"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hətta Wi‑Fi aktiv olanda da mobil datanı həmişə aktiv saxlayın (sürətli şəbəkək keçidi üçün)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Əlçatan oldarsa, birləşmə üçün avadanlıq akselerasiyasından istifadə edin"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB debaq funksiyasına icazə verilsin?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB sazlanması yalnız inkişaf məqsədlidir. Kompüteriniz və cihazınız arasında datanı kopyalamaq üçün ondan istifadə edin, bildiriş olmadan tətbiqləri cihazınıza quraşdırın və qeydiyyat datasını oxuyun."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Əvvəl icazə verdiyiniz kompüterlərdən USB debaq əməliyyatına giriş ləğv olunsun?"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 7a2ee50..fb06a82 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Povezano (bez medija)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezano je (nema pristupa porukama)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezano (bez telefona ili medija)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Povezano, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Povezano (bez telefona), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Povezano (bez medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Povezano (bez telefona ili medija), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski pozivi"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos datoteke"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivan prelaz sa Wi‑Fi mreže na mobilnu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvek dozvoli skeniranje Wi‑Fi-ja u romingu"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje privezivanja"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući glavno podešavanje jačine zvuka"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogućavanje zvonjave na istom kanalu"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija Bluetooth AVRCP-a"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Dozvoli lažne lokacije"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Omogući proveru atributa za pregled"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka mobilni podaci uvek budu aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Koristi hardversko ubrzanje privezivanja ako je dostupno"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Dozvoli otklanjanje USB grešaka?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Otklanjanje USB grešaka namenjeno je samo za svrhe programiranja. Koristite ga za kopiranje podataka sa računara na uređaj i obrnuto, instaliranje aplikacija na uređaju bez obaveštenja i čitanje podataka iz evidencije."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Želite li da opozovete pristup otklanjanju USB grešaka sa svih računara koje ste prethodno odobrili?"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 834e689..f73fd39 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Падключэнне (без носьбіта)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Падлучана (без доступу да паведамленняў)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Падключаны (без тэлефона або носьбіта)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Падключана, узровень зараду акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Падключана (без тэлефона), узровень зараду акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Падключана (без носьбіта), узровень зараду акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Падключана (без тэлефона ці носьбіта), узровень зараду акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аўдыё медыяпрылады"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Тэлефонныя выклікі"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Перадача файлаў"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Інтэнсіўны пераход з Wi‑Fi на маб. сетку"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Заўсёды дазваляць роўмінгавае сканіраванне Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратнае паскарэнне ў рэжыме мадэма"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Адключыць абсалютны гук"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Уключыць унутрыпалосны празвон"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Дазволіць несапраўдныя месцы"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Уключыць прагляд атрыбутаў"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Перадача даных мабільнай сувязі заўсёды актыўна, нават калі актыўна сетка Wi‑Fi (для хуткага пераключэння паміж сеткамі)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Выкарыстоўваць апаратнае паскарэнне ў рэжыме мадэма пры наяўнасці"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Дазволіць адладку USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Адладка USB прызначана толькі для мэтаў распрацоўкі. Яна можа выкарыстоўвацца, каб капіяваць дадзеныя паміж кампутарам і прыладай, усталёўваць прыкладанні на прыладзе без папярэдняга апавяшчэння і чытаць дадзеныя дзённiка."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Адклікаць доступ да адладкі USB з усіх камп\'ютараў, на якiх вы уваходзiлi ў сiстэму?"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index ce9ee56..aa42cce 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Свързано (без мултимедията)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Има връзка (няма достъп до съобщенията)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Свързано (без телефона или мултимедията)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Свързано, батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Свързано (без телефона), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Свързано (без мултимедията), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Свързано (без телефона или мултимедията), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Мултимедийно аудио"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонни обаждания"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Прехвърляне на файл"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi към моб. мрежи: Агресивно предав."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Сканирането за роуминг на Wi-Fi да е разрешено винаги"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Винаги активни мобилни данни"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардуерно ускорение за тетъринга"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Деактивиране на пълната сила на звука"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Активиране на звъненето в една и съща честотна лента"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия на AVRCP за Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Разрешаване на измислени местоположения"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Актив. на инспектирането на атрибутите за преглед"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Мобилните данни са активни винаги – дори когато функцията за Wi‑Fi е включена (за бързо превключване между мрежите)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Да се използва хардуерно ускорение на тетъринга, ако е налице"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Разрешаване на отстраняването на грешки през USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отстраняването на грешки през USB е предназначено само за програмни цели. Използвайте го за копиране на данни между компютъра и устройството си, за инсталиране на приложения на устройството си без известяване и за четене на регистрационни данни."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Да се отмени ли достъпът до отстраняването на грешки през USB от всички по-рано упълномощени от вас компютри?"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 5093a6a..62deb12 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"সংযুক্ত (কোনো মিডিয়া নেই)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"সংযুক্ত (কোনো বার্তা অ্যাক্সেস নেই)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"সংযুক্ত (কোনো ফোন বা মিডিয়া নেই)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"সংযুক্ত হয়েছে, ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"সংযুক্ত হয়েছে (ফোন ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"সংযুক্ত হয়েছে (মিডিয়া ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"সংযুক্ত হয়েছে (ফোন বা মিডিয়া ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়া অডিও"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফোন কল"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ফাইল স্থানান্তর"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ওয়াই-ফাই থেকে মোবাইলে তৎপর হস্তান্তর"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"সর্বদা ওয়াই ফাই রোম স্ক্যানকে অনুমতি দিন"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"চূড়ান্ত ভলিউম অক্ষম করুন"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ইন-ব্যান্ড রিং করা সক্ষম করুন"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ব্লুটুথ AVRCP সংস্করণ"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"মক অবস্থানগুলি মঞ্জুর করুন"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"অ্যাট্রিবিউট পরিদর্শন দেখা সক্ষম করুন"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ওয়াই-ফাই সক্রিয় থাকার সময়েও (দ্রুত নেটওয়ার্কে পাল্টানোর জন্য) সর্বদা মোবাইল ডেটা সক্রিয় রাখুন।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন উপলব্ধ থাকলে ব্যবহার করুন"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ডিবাগিং মঞ্জুর করবেন?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ডিবাগিং কেবলমাত্র বিকাশ করার উদ্দেশ্যে। আপনার কম্পিউটার এবং আপনার ডিভাইসের মধ্যে ডেটা অনুলিপি করতে এটি ব্যবহার করুন, বিজ্ঞপ্তি ছাড়া আপনার ডিভাইসে অ্যাপ্লিকেশানগুলি ইনস্টল করুন এবং ডেটা লগ পড়ুন।"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"আপনি আগে যে সব কম্পিউটার USB ডিবাগিং এর অ্যাক্সেসের অনুমতি দিয়েছিলেন তা প্রত্যাহার করবেন?"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 1af6e30..ca187ab 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -55,14 +55,10 @@
     <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>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Povezano (bez telefona), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Povezano (bez medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Povezano (bez telefona ili medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski pozivi"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenošenje fajla"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivni prijenos s Wi-Fi mreže na mob."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopustiti Wi-Fi lutajuće skeniranje"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna mreža za prijenos podataka je uvijek aktivna"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzavanje dijeljenja veze"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogućite apsolutnu jačinu zvuka"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogući zvono unutar pojasa"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP verzija"</string>
@@ -210,17 +207,18 @@
     <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kada je omogućeno, Wi-Fi veza će u slučaju slabog signala agresivnije predavati vezu za prijenos podataka na mobilnu vezu"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/Zabrani Wi-Fi lutajuće skeniranje na osnovu količine podatkovnog prometa prisutnog na sučelju"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera za zapisnik"</string>
-    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine za Logger prema međumemoriji evidencije"</string>
+    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Odaberite veličine za Logger prema međumemoriji evidencije"</string>
     <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"Želite li izbrisati trajnu pohranu zapisivača?"</string>
     <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"Kada više ne pratimo trajnog zapisivača, trebamo u potpunosti izbrisati podatke zapisivača na vašem uređaju."</string>
     <string name="select_logpersist_title" msgid="7530031344550073166">"Trajno pohranjuj podatke zapisivača na uređaju"</string>
-    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Izaberite međuspremnike zapisnika za trajno pohranjivanje na uređaju"</string>
+    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Odaberite međuspremnike zapisnika za trajno pohranjivanje na uređaju"</string>
     <string name="select_usb_configuration_title" msgid="2649938511506971843">"Odaberite USB konfiguraciju"</string>
     <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Odaberite konfiguraciju USB-a"</string>
     <string name="allow_mock_location" msgid="2787962564578664888">"Dozvoli lažne lokacije"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Dozvoli lažne lokacije"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Omogući pregled atributa prikaza"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Uvijek drži mobilne podatke aktivnim, čak i kada je Wi-Fi je aktivan (za brzo prebacivanje između mreža)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Koristi hardversko ubrzavanje dijeljenja veze, ako je dostupno"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Omogućiti otklanjanje grešaka putem uređaja spojenog na USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Otklanjanje grešaka putem uređaja spojenog na USB je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz zapisnika."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Opozvati pristup otklanjanju grešaka putem uređaja spojenog na USB za sve računare koje ste prethodno ovlastili?"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index a5524ae..5662703 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connectat (sense fitxers multimèdia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connectat (no hi ha accés als missatges)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connectat (sense telèfon o disp. mult.)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connectat (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connectat, sense telèfon (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connectat, sense àudio multimèdia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connectat, sense telèfon ni àudio multimèdia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Àudio multimèdia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Trucades telefòniques"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència del fitxer"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferència agressiva de Wi-Fi a mòbil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permet sempre cerca de Wi-Fi en ininerància"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Acceleració per maquinari per a la compartició de xarxa"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactiva el volum absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activa el so al mateix canal"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versió AVRCP de Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permet les ubicacions simulades"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspecció d\'atributs de visualització"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén les dades mòbils sempre actives, fins i tot quan la Wi‑Fi està activada (per canviar de xarxa ràpidament)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Fes servir l\'acceleració per maquinari per a la compartició de xarxa, si està disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"La depuració USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració d\'USB dels ordinadors que has autoritzat anteriorment?"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 8d82e80..8dd1c32 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Připojeno (žádná média)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Připojeno (bez přístupu ke zprávám)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Připojeno (žádný telefon nebo média)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Připojeno, baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Připojeno (žádný telefon), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Připojeno (žádná média), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Připojeno (žádný telefon ani média), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk médií"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonní hovory"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Přenos souborů"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresivní předání z Wi-Fi na mobilní síť"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povolit Wi-Fi roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilní data jsou vždy aktivní"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarová akcelerace tetheringu"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázat absolutní hlasitost"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Povolit vyzvánění v hovorovém pásmu"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verze profilu Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Povolit simulované polohy"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Kontrola atributu zobrazení"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobilní data budou vždy ponechána aktivní, i když bude aktivní Wi-Fi (za účelem rychlého přepínání sítí)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Pokud je k dispozici hardwarová akceleraci tetheringu, použít ji"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ladění prostřednictvím rozhraní USB je určeno pouze pro účely vývoje. Použijte je ke kopírování dat mezi počítačem a zařízením, instalaci aplikací do zařízení bez upozornění a čtení dat protokolů."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 73662943..143ad92 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Tilsluttet (intet medie)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Forbundet (ingen adgang til meddelelse)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Forbundet (ingen telefon eller medier)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Tilsluttet – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Tilsluttet (ingen telefon) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Tilsluttet (ingen medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Tilsluttet (ingen telefon eller medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonopkald"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverførsel"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Tvungen skift fra Wi-Fi til mobildata"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillad altid scanning af Wi-Fi-roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er altid aktiveret"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareacceleration ved netdeling"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiver absolut lydstyrke"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Afspil ringetone via Bluetooth"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version for Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Tillad imiterede placeringer"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktivér visning af attributinspektion"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hold altid mobildata aktiveret, selv når Wi-Fi er aktiveret (for at skifte hurtigt mellem netværk)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Brug hardwareacceleration ved netdeling, hvis det er muligt"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Vil du tillade USB-fejlretning?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-fejlretning er kun beregnet til udvikling og kan bruges til at kopiere data mellem din computer og enheden, installere apps på enheden uden meddelelser og læse logdata."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vil du ophæve adgangen til USB-fejlfinding for alle computere, du tidligere har godkendt?"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index ccfa675..fda1aa4 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Verbunden (außer Audiomedien)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Verbunden (ohne Nachrichtenzugriff)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Verbunden (außer Telefon- und Audiomedien)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Verbunden, Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Verbunden (außer Telefon), Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Verbunden (außer Medienwiedergabe), Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Verbunden (außer Telefon und Medienwiedergabe), Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-Audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonanrufe"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dateiübertragung"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressives Handover von WLAN an Mobilfunk"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"WLAN-Roamingsuchen immer zulassen"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile Datennutzung immer aktiviert"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarebeschleunigung für Tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Maximallautstärke deaktivieren"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"In-Band-Klingeln aktivieren"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-Version"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Simulierte Standorte zulassen"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspektion der Anzeigeattribute aktivieren"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Die mobile Datennutzung bleibt auch dann aktiviert, wenn WLAN aktiviert ist. Dies dient einem schnelleren Wechsel zwischen Netzwerken."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Falls verfügbar, Hardwarebeschleunigung für Tethering verwenden"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB-Debugging zulassen?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-Debugging ist nur für Entwicklungszwecke vorgesehen. Damit kannst du Daten zwischen deinem Computer und deinem Gerät kopieren, Apps auf deinem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zugriff auf USB-Debugging für alle zuvor autorisierten Computer aufheben?"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index e424b28..244af42 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Συνδεδεμένο (όχι μέσα)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Συνδεδεμένο (χωρίς πρόσβαση μηνύματος)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Συνδεδεμένο (χωρίς τηλέφωνο ή πολυμέσα)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Συνδεδεμένη, μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Συνδεδεμένη (όχι τηλέφωνο), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Συνδεδεμένη (όχι πολυμέσα), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Συνδεδεμένη (όχι τηλέφωνο ή πολυμέσα), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Ήχος πολυμέσων"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Τηλεφωνικές κλήσεις"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Μεταφορά αρχείου"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Επιθ.μεταβ. Wi-Fi σε δίκτυο κιν.τηλ."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Να επιτρέπεται πάντα η σάρωση Wi-Fi κατά την περιαγωγή"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Σύνδεση επιτάχυνσης υλικού"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Απενεργοποίηση απόλυτης έντασης"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ενεργοποίηση κλήσης εντός εύρους"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Έκδοση AVRCP Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Να επιτρέπονται ψευδείς τοποθεσίες"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ενεργοποίηση του ελέγχου χαρακτηριστικών προβολής"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Τα δεδομένα κινητής τηλεφωνίας να διατηρούνται πάντα ενεργά, ακόμα και όταν είναι ενεργό το Wi-Fi (για γρήγορη εναλλαγή δικτύου)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Χρήση της σύνδεσης επιτάχυνσης υλικού εάν υπάρχει"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Να επιτρέπεται ο εντοπισμός σφαλμάτων USB;"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ο εντοπισμός σφαλμάτων USB προορίζεται μόνο για σκοπούς προγραμματισμού. Χρησιμοποιήστε τον για αντιγραφή δεδομένων μεταξύ του υπολογιστή και της συσκευής σας, για την εγκατάσταση εφαρμογών στη συσκευή σας χωρίς προειδοποίηση και για την ανάγνωση δεδομένων καταγραφής."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Ανάκληση πρόσβασης στον εντοπισμό σφαλμάτων USB από όλους τους υπολογιστές για τους οποίους είχατε εξουσιοδότηση στο παρελθόν;"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index de32f3c..09ad05c 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connected (no media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connected (no message access)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connected (no phone or media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Enable in-band ringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification and read log data."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you\'ve previously authorised?"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index de32f3c..09ad05c 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connected (no media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connected (no message access)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connected (no phone or media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Enable in-band ringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification and read log data."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you\'ve previously authorised?"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index de32f3c..09ad05c 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connected (no media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connected (no message access)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connected (no phone or media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Enable in-band ringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification and read log data."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you\'ve previously authorised?"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index f261cbf..7e21d6c 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sin audio multimedia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sin acceso a mensajes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sin tel. ni audio multimedia)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado. Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado (sin teléfono). Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado (sin audio multimedia). Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado (sin teléfono ni audio multimedia). Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Llamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de archivos"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Priorizar cambio de red Wi-Fi a móvil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activados"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware de conexión mediante dispositivo portátil"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Habilitar sonido dentro de banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión de AVRCP del Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir ubicaciones de prueba"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Habilitar inspección de atributos de vista"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Siempre mantén los datos móviles activos, incluso cuando esté activada la conexión Wi‑Fi (para cambiar de red de forma rápida)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar la aceleración de hardware de conexión mediante dispositivo portátil si está disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"¿Permitir depuración por USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"La depuración por USB solo está indicada para actividades de programación. Úsala para copiar datos entre tu computadora y el dispositivo, para instalar aplicaciones en el dispositivo sin recibir notificaciones y para leer datos de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"¿Quieres revocar el acceso a la depuración por USB desde todas la computadoras que autorizaste hasta ahora?"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index d52ac06..e2e0e62 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sin audio multimedia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sin acceso a mensajes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sin teléfono ni multimedia)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado sin teléfono (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado sin audio multimedia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado sin teléfono ni audio multimedia (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Llamadas de teléfono"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de archivos"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferencia agresiva de Wi-Fi a móvil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración por hardware para conexión mediante dispositivo portátil"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Habilitar tono de llamada por Bluetooth"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP del Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir ubicaciones simuladas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspección de atributos de vista"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén los datos móviles siempre activos, aunque la conexión Wi‑Fi esté activada (para cambiar de red rápidamente)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar la aceleración por hardware para conexión mediante dispositivo portátil si está disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"¿Permitir depuración por USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"La depuración por USB solo está indicada para actividades de desarrollo. Puedes utilizarla para intercambiar datos entre el ordenador y el dispositivo, para instalar aplicaciones en el dispositivo sin recibir notificaciones y para leer datos de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"¿Quieres revocar el acceso a la depuración por USB de todos los ordenadores que has autorizado?"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 5cb3e2a..f3748f8 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ühendatud (meediat pole)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ühendatud (sõnumita juurdepääs)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ühendatud (pole telefoni ega meediat)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ühendatud, aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ühendatud (telefoni pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ühendatud (meediat pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ühendatud (telefoni ega meediat pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meedia heli"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonikõned"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failiedastus"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agress. üleminek WiFi-lt mobiilsidele"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luba alati WiFi-rändluse skannimine"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilne andmeside on alati aktiivne"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Jagamise riistvaraline kiirendus"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Keela absoluutne helitugevus"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Luba ribasisene helisemine"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothi AVRCP versioon"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Luba võltsasukohti"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Luba kuva atribuudi hindamine"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hoidke mobiilne andmeside alati aktiivsena, isegi kui WiFi on aktiivne (võrkude kiireks vahetamiseks)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Kasuta võimalusel jagamise riistvaralist kiirendust"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Luban USB silumise?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-silumine on mõeldud ainult arendamiseks. Kasutage seda andmete kopeerimiseks oma arvuti ja seadme vahel, seadmesse rakenduste installimiseks ilma teatisteta ning logiandmete lugemiseks."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Kas tühistada juurdepääs USB silumisele kõikides arvutites, mille olete varem volitanud?"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index e4b6c95..9fd8ad84 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Konektatuta (ez dago euskarririk)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Konektatuta (mezuetarako sarbiderik ez)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Konektatuta (ez dago telef./euskarririk)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Konektatuta. Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Konektatuta (telefonorik gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Konektatuta (euskarririk gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Konektatuta (telefono edo euskarririk gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Euskarriaren audioa"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefono-deiak"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fitxategi-transferentzia"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Behartu Wi-Fi konexiotik datuenera aldatzera"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Onartu beti ibiltaritzan Wi-Fi sareak bilatzea"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datu mugikorrak beti aktibo"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Konexioa partekatzeko hardwarearen azelerazioa"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desgaitu bolumen absolutua"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Gaitu tonuak audio-kanal berean erreproduzitzeko aukera"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP bertsioa"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Onartu kokapen faltsuak"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantendu mugikorreko datuak beti aktibo, baita Wi-Fi konexioa aktibo dagoenean ere (sarez bizkor aldatu ahal izateko)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen azelerazioa"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB arazketa onartu?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB arazketa garapen-xedeetarako soilik dago diseinatuta. Erabil ezazu ordenagailuaren eta gailuaren artean datuak kopiatzeko, aplikazioak gailuan jakinarazi gabe instalatzeko eta erregistro-datuak irakurtzeko."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Aurretik baimendutako ordenagailu guztiei USB arazketarako sarbidea baliogabetu nahi diezu?"</string>
@@ -289,7 +287,7 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Atzeko planoko prozesuen muga"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Erakutsi ANR guztiak"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"\"Erantzunik ez\" mezua atz. planoko aplikazioetarako"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Erakutsi jakinarazpenen kanaleko abisuak"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Erakutsi jakinarazpenen kanalen abisuak"</string>
     <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Bistaratu abisuak aplikazioek baliozko kanalik gabeko jakinarazpenak argitaratzean"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Behartu aplikazioak onartzea kanpoko biltegian"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Aplikazioek kanpoko memorian idatz dezakete, manifestuaren balioak kontuan izan gabe"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index bf10b1a..0430592 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"متصل شد (بدون رسانه)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"متصل (عدم دسترسی به پیام)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"متصل شد (بدون تلفن یا رسانه)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"متصل، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"متصل (بدون تلفن)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"متصل (بدون رسانه)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"متصل (بدون تلفن یا رسانه)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"رسانه صوتی"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"تماس‌های تلفنی"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"انتقال فایل"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏Wi‑Fi قوی برای واگذاری به دستگاه همراه"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏اسکن‌های رومینگ Wi‑Fi همیشه مجاز است"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"داده تلفن همراه همیشه فعال باشد"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"شتاب سخت‌افزاری اتصال به اینترنت با تلفن همراه"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"غیرفعال کردن میزان صدای مطلق"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"فعال کردن زنگ زدن درون باندی"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏نسخه AVRCP بلوتوث"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"مکان‌های کاذب مجاز هستند"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"فعال کردن نمایش بازبینی ویژگی"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏داده سلولی همیشه فعال نگه داشته می‌شود، حتی وقتی Wi-Fi فعال است (برای جابه‌جایی سریع شبکه)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"استفاده از شتاب سخت‌افزاری اتصال به اینترنت با تلفن همراه درصورت دردسترس بودن"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏اشکال‌زدایی USB انجام شود؟"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏اشکال‌زدایی USB فقط برای اهداف برنامه‌نویسی در نظر گرفته شده است. از آن برای رونوشت‌برداری داده بین رایانه و دستگاهتان، نصب برنامه‌ها در دستگاهتان بدون اعلان و خواندن داده‌های گزارش استفاده کنید."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏دسترسی به اشکال‌زدایی USB از تمام رایانه‌هایی که قبلاً مجاز دانسته‌اید لغو شود؟"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 42a0127..e3a92e6 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Yhdistetty (ei median ääntä)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Yhdistetty (ei MAP)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Yhdistetty (ei puhelimen/median ääntä)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Yhdistetty, akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Yhdistetty (ei puhelimen ääntä), akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Yhdistetty (ei median ääntä), akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Yhdistetty (ei puhelimen tai median ääntä), akun varaustaso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Median ääni"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Puhelut"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Tiedostonsiirto"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Vaihda herkästi Wi-Fi mobiiliyhteyteen"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Salli Wi-Fi-verkkovierailuskannaus aina"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilidata aina käytössä"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Laitteistokiihdytyksen yhteyden jakaminen"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Poista yleinen äänenvoimakkuuden säätö käytöstä"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ota käyttöön kaistalla soitto"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetoothin AVRCP-versio"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Salli sijaintien imitointi"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ota attribuuttinäkymän tarkistus käyttöön"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Pidä mobiilidata aina käytössä, vaikka Wi-Fi olisi aktiivinen. Tämä mahdollistaa nopeamman vaihtelun verkkojen välillä."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Käytä laitteistokiihdytyksen yhteyden jakamista, jos se on käytettävissä"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Sallitaanko USB-vianetsintä?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-vianetsintä on tarkoitettu vain kehittäjien käyttöön. Sen avulla voidaan kopioida tietoja tietokoneesi ja laitteesi välillä, asentaa laitteeseesi sovelluksia ilmoittamatta siitä sinulle ja lukea lokitietoja."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Haluatko peruuttaa USB-vianetsinnän käyttöoikeuden kaikilta tietokoneilta, joille olet antanut luvan aiemmin?"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 88fd9cb..99692a6 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connecté (sans audio contenu mutimédia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connecté (sans accès aux messages)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connecté (sans audio tel./multimédia)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connecté. Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connecté (sans téléphone). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connecté (sans média). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connecté (sans téléphone ni média). Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Paramètres audio du support"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé du Wi-Fi aux données cell."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données cellulaires toujours actives"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activer la signalisation intra-bande"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version du profil Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Autoriser les positions fictives"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activer l\'inspection d\'attribut d\'affichage"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Toujours garder les données cellulaires actives, même lorsque le Wi-Fi est activé (pour la commutation rapide entre les réseaux)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Utiliser l\'accélération matérielle du partage de connexion si possible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Autoriser le débogage USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Voulez-vous vraiment désactiver l\'accès au débogage USB de tous les ordinateurs précédemment autorisés?"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index c5f951d..2593c16 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connecté (sans audio contenu mutimédia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connecté (sans accès aux messages)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connecté (sans audio tel./multimédia)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connecté, batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connecté (aucun téléphone), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connecté (aucun contenu multimédia), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connecté (aucun téléphone ni contenu multimédia), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multimédia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Passage forcé Wi-Fi vers données mobiles"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données mobiles toujours actives"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activer la signalisation intra-bande"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Version Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Autoriser les positions fictives"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activer inspect. attribut affich."</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Maintenir l\'état actif des données mobiles, même lorsque le Wi‑Fi est actif (pour changer rapidement de réseau)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Utiliser l\'accélération matérielle pour le partage de connexion, si disponible"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Autoriser le débogage USB ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Voulez-vous vraiment désactiver l\'accès au débogage USB de tous les ordinateurs précédemment autorisés ?"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index d60d072..1a6fd39 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sen ficheiros multimedia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sen acceso ás mensaxes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (ningún teléfono nin soporte)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Dispositivo conectado. Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Dispositivo conectado (sen teléfono). Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Dispositivo conectado (sen audio multimedia). Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Dispositivo conectado (sen teléfono nin audio multimedia). Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de ficheiros"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Transferencia agresiva de wifi a móbil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre buscas de itinerancia da wifi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móbiles sempre activados"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware para conexión compartida"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactivar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activar a función de soar na mesma banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versión AVRCP de Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permite localizacións falsas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Activar a inspección de atributos de visualización"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén sempre os datos móbiles activos, aínda que a wifi estea activada (para un rápido cambio de rede)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Se está dispoñible, úsase a aceleración de hardware para conexión compartida"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Queres permitir a depuración USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuración de erros USB está deseñada unicamente para fins de programación. Utilízaa para copiar datos entre o ordenador e o dispositivo, instalar aplicacións no dispositivo sen enviar notificacións e ler os datos do rexistro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Queres revogar o acceso á depuración USB desde todos os ordenadores que autorizaches previamente?"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 20d92f2..674d4c9 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"કનેક્ટ કર્યું (મીડિયા નથી)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"કનેક્ટ કર્યું (કોઇ સંદેશ ઍક્સેસ નથી)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"કનેક્ટ કરેલ (કોઈ ફોન અથવા મીડિયા નથી)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"કનેક્ટ કરેલ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"કનેક્ટ કરેલ (કોઈ ફોન નથી), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"કનેક્ટ કરેલ (કોઈ મીડિયા નથી), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"કનેક્ટ કરેલ (કોઈ ફોન અથવા મીડિયા નથી), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"મીડિયા ઑડિઓ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ફોન કૉલ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ફાઇલ સ્થાનાંતરણ"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"સશક્ત Wi‑Fiથી મોબાઇલ પર હૅન્ડઓવર"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"હંમેશા Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ચોક્કસ વૉલ્યૂમને અક્ષમ કરો"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"બેંડમાં રિંગ કરવાનું સક્ષમ કરો"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP સંસ્કરણ"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"મોક સ્થાનોની મંજૂરી આપો"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"લક્ષણ નિરીક્ષણ જોવાનું સક્ષમ કરો"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi  સક્રિય હોય ત્યારે પણ, હંમેશા મોબાઇલ ડેટાને સક્રિય રાખો (ઝડપી નેટવર્ક સ્વિચિંગ માટે)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"જો ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ ઉપલબ્ધ હોય તો તેનો ઉપયોગ કરો"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ડિબગિંગને મંજૂરી આપીએ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ડિબગીંગ ફક્ત વિકાસ હેતુઓ માટે જ બનાવાયેલ છે. તેનો ઉપયોગ તમારા કમ્પ્યુટર અને તમારા ઉપકરણ વચ્ચે ડેટાને કૉપિ કરવા, સૂચના વગર તમારા ઉપકરણ પર ઍપ્લિકેશનો ઇન્સ્ટોલ કરવા અને લૉગ ડેટા વાંચવા માટે કરો."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"તમે અગાઉ અધિકૃત કરેલા તમામ કમ્પ્યુટર્સમાંથી USB ડિબગિંગ પરની અ‍ૅક્સેસ રદબાતલ કરીએ?"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 217099d..dd9ad33 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"कनेक्‍ट है (मीडि‍या नहीं)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"कनेक्ट किया गया (कोई संदेश एक्सेस नहीं)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"कनेक्‍ट है (फ़ोन या मीडि‍या नहीं)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"कनेक्ट किया गया, बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"कनेक्ट किया गया (कोई फ़ोन नहीं), बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"कनेक्ट किया गया (कोई मीडिया नहीं), बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"कनेक्ट किया गया (कोई फ़ोन या मीडि‍या नहीं), बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडियो"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फ़ोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फ़ाइल स्थानांतरण"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"वाई-फ़ाई से मोबाइल पर ज़्यादा तेज़ी से हैंडओवर"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"हमेशा वाई-फ़ाई रोम स्कैन करने दें"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा हमेशा सक्रिय"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"हार्डवेयर त्‍वरण को टेदर करना"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"पूर्ण वॉल्यूम अक्षम करें"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"इन-बैंड रिंग करना सक्षम करें"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लूटूथ AVRCP वर्शन"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"कृत्रिम स्‍थानों को अनुमति दें"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"दृश्य विशेषता निरीक्षण सक्षम करें"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"वाई-फ़ाई के सक्रिय रहने पर भी, हमेशा मोबाइल डेटा सक्रिय रखें (तेज़ी से नेटवर्क स्विच करने के लिए)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"हार्डवेयर त्‍वरण को टेदर करना उपलब्ध होने पर उसका उपयोग करें"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डीबग करने की अनुमति दें?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग डीबग करने का उद्देश्‍य केवल विकास है. इसका उपयोग आपके कंप्‍यूटर और आपके डिवाइस के बीच डेटा की प्रतिलिपि बनाने, बिना नोटिफिकेशन के आपके डिवाइस पर ऐप्स इंस्‍टॉल करने और लॉग डेटा पढ़ने के लिए करें."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"आपके द्वारा पूर्व में प्राधिकृत सभी कंप्यूटर से USB डीबगिंग की पहुंच निरस्त करें?"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 6c4f293..8ba4034 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -55,14 +55,10 @@
     <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 telefona ili medija)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Povezano (bez telefona), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Povezano (bez medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Povezano (bez telefona i medija), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medijski zvuk"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski pozivi"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prijenos datoteke"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aktivni prijelaz s Wi‑Fi na mob. mrežu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopusti slobodno traženje Wi-Fi mreže"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci uvijek aktivni"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje za modemsko povezivanje"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući apsolutnu glasnoću"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogući zvuk zvona unutar pojasne širine"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzija AVRCP-a za Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Dopusti probne lokacije"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Omogući pregled atributa prikaza"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka mobilni podaci uvijek budu aktivni, čak i kada je Wi‑Fi aktivan (za brzo prebacivanje s jedne na drugu mrežu)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Upotreba hardverskog ubrzanja za modemsko povezivanje ako je dostupno"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Omogućiti otklanjanje pogrešaka putem USB-a?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Otklanjanje pogrešaka putem USB-a namijenjeno je samo u razvojne svrhe. Može se upotrijebiti za kopiranje podataka s računala na uređaj i obrnuto, instalaciju aplikacija na uređaju bez obavijesti i za čitanje dnevničkih zapisa."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Želite li opozvati pristup uklanjanju pogrešaka putem USB-a sa svih računala koja ste prethodno autorizirali?"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 479290f..a544125 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Csatlakoztatva (nincs hordozó)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Csatlakoztatva (nincs üzenet-hozzáférés)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Csatlakoztatva (nincs telefon vagy hordozó)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Csatlakoztatva; az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Csatlakoztatva (telefonhang nélkül); az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Csatlakoztatva (médiahang nélkül); az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Csatlakoztatva (telefon- vagy médiahang nélkül); az akkumulátor töltöttségi szintje:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Média audió"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonhívások"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fájlátvitel"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresszív Wi‑Fi–mobilhálózat átadás"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi-roaming ellenőrzésének engedélyezése mindig"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"A mobilhálózati kapcsolat mindig aktív"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Internetmegosztás hardveres gyorsítása"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Abszolút hangerő funkció letiltása"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Sávon belüli csörgetés engedélyezése"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"A Bluetooth AVRCP-verziója"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Helyutánzatok engedélyezése"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Nézetattribútum vizsgálatának engedélyezése"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"A mobiladat-kapcsolat mindig maradjon aktív, még akkor is, ha a Wi‑Fi aktív (a gyors hálózatváltás érdekében)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Az internetmegosztás hardveres gyorsításának használata, amikor lehetséges"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Engedélyezi az USB hibakeresést?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Az USB hibakeresés fejlesztési célokat szolgál. Használhatja adatok másolására a számítógép és a készülék között, alkalmazások a készülékre való értesítés nélküli telepítésére és naplózási adatok olvasására."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Visszavonja a hozzáférést az USB-s hibakereséshez az összes számítógépről, ahol korábban engedélyezte azt?"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index ec6c1a2..cb04234 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Միացված է (առանց մեդիա)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Միացված է (հաղորդագրությանը մուտք չկա)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Միացված է (առանց հեռախոսի և մեդիայի)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Միացված է, մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Միացած է (հեռախոս չկա), մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Միացված է (մեդիա չկա), մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Միացված է (հեռախոս կամ մեդիա չկա), մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Մեդիա աուդիո"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Հեռախոսազանգեր"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Ֆայլերի փոխանցում"</string>
@@ -73,8 +69,8 @@
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Ինտերնետ կապի տարածում"</string>
     <string name="bluetooth_profile_map" msgid="1019763341565580450">"SMS հաղորդագրություններ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM քարտի հասանելիություն"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ձայն՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ձայն"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD աուդիո՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD աուդիո"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Միացված է մեդիա աուդիոյին"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Միացված է հեռախոսի ձայնային տվյալներին"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Միացված է ֆայլերի փոխանցման սերվերին"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi-ից կտրուկ անցում բջջային ինտերնետի"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Միշտ թույլատրել Wi‑Fi ռոումինգի որոնումը"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Բջջային ինտերնետը միշտ ակտիվ է"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Սարքակազմի արագացման միացում"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Անջատել ձայնի բացարձակ ուժգնությունը"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Միացնել ներխմբային զանգը"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP տարբերակը"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Թույլ տալ կեղծ տեղադրություններ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Միացնել ցուցադրման հատկանիշների ստուգումը"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Միշտ ակտիվացրած պահել բջջային տվյալները, նույնիսկ Wi‑Fi-ը միացրած ժամանակ (ցանցերի միջև արագ փոխարկման համար):"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Օգտագործել սարքակազմի արագացման միացումը, եթե հասանելի է"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB-ի վրիպազերծումը:"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB վրիպազերծումը միայն ծրագրավորման նպատակների համար է: Օգտագործեք այն ձեր համակարգչից տվյալները ձեր սարք պատճենելու համար, առանց ծանուցման ձեր սարքի վրա ծրագրեր տեղադրելու և տվյալների մատյանը ընթերցելու համար:"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Փակե՞լ USB-ի վրիպազերծման մուտքը` անջատելով այն բոլոր համակարգիչներից, որտեղ նախկինում թույլատրել էիք:"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 6027821..a8dd4c2 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Terhubung (kecuali media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Tersambung (tidak ada akses pesan)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Terhubung (bukan telepon atau media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Terhubung, baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Terhubung (tanpa ponsel), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Terhubung (tanpa media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Terhubung (tanpa ponsel atau media), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Panggilan telepon"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer file"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Pengalihan Wi-Fi Agresif ke seluler"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Selalu izinkan Pemindaian Roaming Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Data seluler selalu aktif"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akselerasi hardware tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Nonaktifkan volume absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktifkan dering in-band"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Mengizinkan lokasi palsu"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktifkan inspeksi atribut tampilan"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Selalu aktifkan data seluler, meski Wi-Fi aktif (agar jaringan beralih dengan cepat)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gunakan akselerasi hardware tethering jika tersedia"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Izinkan melakukan debug USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Debugging USB dimaksudkan untuk tujuan pengembangan saja. Gunakan untuk menyalin data antara komputer dan perangkat Anda, memasang apl pada perangkat tanpa notifikasi, dan membaca data log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Cabut akses ke debug USB dari semua komputer yang telah Anda otorisasi sebelumnya?"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 4db2d5e..7f541ce 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Tengt (ekki efnisspilun)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Tengt (enginn skilaboðaaðgangur)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Tengt (ekki sími eða efnisspilun)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Tengt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Tengt (ekki sími), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Tengt (ekki efnisspilun), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Tengt (ekki sími eða efnisspilun), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Hljóð efnis"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Símtöl"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Skráaflutningur"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Hröð skipti úr Wi‑Fi í farsímagögn"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Leyfa alltaf reikileit með Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Alltaf kveikt á farsímagögnum"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Vélbúnaðarhröðun fyrir tjóðrun"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slökkva á samstillingu hljóðstyrks"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Leyfa símtöl á sömu rás"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-útgáfa"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Leyfa gervistaðsetningar"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Virkja yfirlit skoðunar eiginda"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hafa alltaf kveikt á farsímagögnum, líka þegar kveikt er á Wi-Fi (til að skipta megi hratt milli kerfa)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Nota vélbúnaðarhröðun fyrir tjóðrun ef það býðst"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Leyfa USB-villuleit?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-villuleit er aðeins ætluð til nota í þróunarskyni. Hana má nota til að afrita gögn á milli tölvu og tækis, setja forrit upp í tækinu án tilkynninga og lesa annálagögn."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Afturkalla aðgang að USB-villuleit í öllum tölvum sem þú hefur áður veitt heimild?"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 2ab2f7e..5598d87 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Collegato (contenuti multimed. esclusi)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connesso (nessun accesso ai messaggi)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Collegato (telef. o conten. mult. esclusi)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connesso, batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connesso (telefono escluso), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connesso (contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connesso (telefono o contenuti multimediali esclusi), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimediale"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonate"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Trasferimento file"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi aggressivo per passaggio a cellulare"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Consenti sempre scansioni roaming Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering accelerazione hardware"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disattiva volume assoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Attiva suoneria in banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versione Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Consenti posizioni fittizie"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Attiva controllo attributi visualizzazione"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantieni sempre i dati cellulare attivi, anche se il Wi‑Fi è attivo (per un passaggio fra reti rapido)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Utilizza l\'accelerazione hardware per il tethering se disponibile"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Consentire debug USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Il debug USB è solo a scopo di sviluppo. Utilizzalo per copiare dati tra il computer e il dispositivo, per installare applicazioni sul tuo dispositivo senza notifica e per leggere i dati dei log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revocare l\'accesso al debug USB da tutti i computer precedentemente autorizzati?"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 5c9ef23..26ce32e 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"מחובר (ללא מדיה)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"מחובר (אין גישה להודעות)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"מחובר (ללא טלפון או מדיה)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"מחובר, הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"מחובר (ללא טלפון), הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"מחובר (ללא מדיה), הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"מחובר (ללא טלפון וללא מדיה), הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"אודיו של מדיה"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"שיחות טלפון"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"העברת קבצים"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏העברה אגרסיבית מ-Wi‑Fi לרשת סלולרית"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏התר תמיד סריקות נדידה של Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"חבילת הגלישה פעילה תמיד"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"שיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"השבת עוצמת קול מוחלטת"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"‏הפעל צלצולים בערוץ ה-Bluetooth‏ (in-band ringing)"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏Bluetooth גרסה AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"אפשר מיקומים מדומים"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"אפשר בדיקת תכונת תצוגה"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏השאר את חבילת הגלישה פעילה תמיד, גם כש-Wi‑Fi פעיל (למעבר מהיר בין רשתות)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"אם השירות זמין, יש להשתמש בשיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏לאפשר ניפוי באגים של USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏ניפוי באגים באמצעות USB מיועד למטרות פיתוח בלבד. השתמש בו להעתקת נתונים בין המחשב והמכשיר שלך, להתקנת אפליקציות במכשיר ללא התראה ולקריאת נתוני יומן."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏האם לבטל את הגישה לניפוי ב-USB מכל המחשבים שהענקת להם בעבר הרשאה?"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 0d6334d..30c7267 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"接続済み(メディアを除く)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"接続済み(メッセージへのアクセスなし)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"接続済み(電話/メディアを除く)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"接続済み、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"接続済み(スマートフォンを除く)、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"接続済み(メディアを除く)、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"接続済み(スマートフォンやメディアを除く)、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"メディアの音声"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"電話"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ファイル転送"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi を強制的にモバイル接続に切り替える"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fiローミングスキャンを常に許可する"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"モバイルデータを常に ON にする"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"テザリング時のハードウェア アクセラレーション"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"絶対音量を無効にする"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"インバンド リンギングを有効にする"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP バージョン"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"擬似ロケーションを許可する"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"表示属性検査を有効にする"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fiが(ネットワークの自動切り替えで)ONのときでもモバイルデータが常にONになります。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"テザリング時にハードウェア アクセラレーションを使用します(使用可能な場合)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USBデバッグを許可しますか?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USBデバッグは開発専用に設計されています。パソコンと端末の間でデータをコピーする場合や、アプリを通知なしで端末にインストールする場合、ログデータを読み取る場合に使用できます。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"以前に許可したすべてのパソコンからのUSBデバッグへのアクセスを取り消しますか?"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index c48018d..553c4a0 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"მიერთებულია (მედიის გარდა)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"დაკავშირებულია (შეტყობინებაზე წვდომა არ არის)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"დაკავშირება (გარდა ტელეფონისა და მედიისა)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"დაკავშირებულია. ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"დაკავშირებულია (ტელეფონი არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"დაკავშირებულია (მედია არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"დაკავშირებულია (მედია ან ტელეფონი არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"მედია აუდიო"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"სატელეფონო ზარები"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ფაილების გადაცემა"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi-ს მობ. ინტერნეტზე აგრესიული გადართვა"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Roam სკანირების მუდამ დაშვება"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ტეტერინგის აპარატურული აჩქარება"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ხმის აბსოლუტური სიძლიერის გათიშვა"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ზოლსშიდა დარეკვის ჩართვა"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-ის AVRCP-ის ვერსია"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ფიქტიური მდებარეობების დაშვება"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ნახვის ატრიბუტის ინსპექტირების ჩართვა"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"მობილური მოწყობილობის მონაცემები ყოველთვის აქტიური დარჩეს, მაშინაც კი, როდესაც Wi-Fi აქტიურია (ქსელის სწრაფი გადართვისთვის)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ტეტერინგის აპარატურული აჩქარების ხელმისაწვდომობის შემთხვევაში გამოყენება"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"ჩაირთოს USB გამართვა?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB გამართვა განკუთვნილია მხოლოდ დეველოპერული მიზნებისთვის. გამოიყენეთ კომპიუტერსა და თქვენ მოწყობილობას შორის მონაცემების გადასატანად, თქვენ მოწყობილობაზე აპების შეტყობინების გარეშე დასაყენებლად და ჟურნალის მონაცემების წასაკითხად."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"გავაუქმოთ ყველა იმ კომპიუტერიდან USB გამართვაზე წვდომა, რომლებიდანაც აქამდე განახორციელეთ შესვლა?"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index be03821..27622a1 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Жалғанған (медиа жоқ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Жалғанған (хабарлар қол жетімсіз)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Жалғанған (телефон және медиа жоқ)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Қосылды, батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Қосылды (телефон емес), батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Қосылды (медиа емес), батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Қосылды (телефон не медиа емес), батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meдиа аудиосы"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефон қоңыраулары"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл жіберу"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi желісінен мобильдік желіге ауысу"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi роумингін іздеулерге әрқашан рұқсат ету"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетерингтің аппараттық жеделдетуі"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Абсолютті дыбыс деңгейін өшіру"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ішкі жолақтағы шылдырлауды қосу"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP нұсқасы"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Жасанды аймақтарды пайдалануға рұқсат беру"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Көру төлсипатын тексеруді қосу"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi қосулы кезде де ұялы деректерді белсенді етіп ұстау (желіні жылдам ауыстыру үшін)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Қолжетімді болса тетерингтің аппараттық жеделдетуін пайдалану"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB жөндеулеріне рұқсат берілсін бе?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB жөндеу дамыту мақсаттарына ғана арналған. Оны компьютер және құрылғы арасында дерек көшіру, құрылғыға ескертусіз қолданба орнату және тіркелім деректерін оқу үшін қолданыңыз."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Бұған дейін рұқсат берілген барлық компьютерлерде USB жөндеу функциясына тыйым салынсын ба?"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index d8fac16..5f614f6 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"បាន​តភ្ជាប់ (គ្មាន​មេឌៀ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"បាន​ភ្ជាប់ (គ្មាន​ការ​ចូល​ដំណើរការ​សារ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"បាន​តភ្ជាប់ (គ្មាន​ទូរស័ព្ទ ឬ​មេឌៀ)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"បានភ្ជាប់ ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"បានភ្ជាប់ (គ្មានទូរសព្ទ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"បានភ្ជាប់ (គ្មានមេឌៀ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"បានភ្ជាប់ (គ្មានទូរសព្ទ ឬមេឌៀ) ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"សំឡេង​មេឌៀ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ការហៅ​ទូរសព្ទ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ផ្ទេរ​ឯកសារ"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ប្តូរទៅប្រើបណ្តាញចល័តពេល Wi‑Fi មានរលកសញ្ញាខ្លាំងពេក"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"តែងតែ​អនុញ្ញាត​​​ការវិភាគ​រ៉ូម​វ៉ាយហ្វាយ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ការ​បង្កើនល្បឿន​ផ្នែករឹងសម្រាប់​ការភ្ជាប់"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"បិទកម្រិតសំឡេងលឺខ្លាំង"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"បើក​ការ​រោទ៍​ក្នុងបណ្តាញ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"កំណែប្ល៊ូធូស AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"អនុញ្ញាត​ទីតាំង​ក្លែងក្លាយ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"បើក​ការ​ត្រួតពិនិត្យ​គុណ​លក្ខណៈ​ទិដ្ឋភាព"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"រក្សាទិន្នន័យចល័តឲ្យសកម្មជានិច្ច បើទោះបីជា Wi‑Fi សកម្មក៏ដោយ (សម្រាប់ការប្តូរបណ្តាញដែលមានល្បឿនលឿន)។"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ប្រើការ​បង្កើនល្បឿន​ផ្នែករឹងសម្រាប់​ការភ្ជាប់​ ប្រសិន​បើអាច​ប្រើបាន"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"អនុញ្ញាត​ការ​កែ​កំហុស​យូអេសប៊ី?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"ការ​កែ​កំហុស​​យូអេសប៊ី​គឺ​សម្រាប់​តែ​ការ​អភិវឌ្ឍ​ប៉ុណ្ណោះ។ ប្រើ​វា​ដើម្បី​ចម្លង​ទិន្នន័យ​រវាង​កុំព្យូទ័រ និង​ឧបករណ៍​របស់​អ្នក ដំឡើង​កម្មវិធី​ក្នុង​ឧបករណ៍​របស់​អ្នក​ដោយ​មិន​ជូន​ដំណឹង និង​អាន​ទិន្នន័យ​កំណត់ហេតុ។"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ដក​សិទ្ធិ​ចូល​ការ​កែ​កំហុស​តាម​យូអេសប៊ី​ពី​គ្រប់​កុំព្យូទ័រ​ដែល​អ្នក​បាន​ផ្ដល់​សិទ្ធិ​ពី​មុន?"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 3989e98..c74b7be 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಮಾಧ್ಯಮವಿಲ್ಲ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ (ಯಾವುದೇ ಸಂದೇಶ ಪ್ರವೇಶವಿಲ್ಲ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಅಥವಾ ಮಾಧ್ಯಮವಿಲ್ಲ)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ಸಂಪರ್ಕಗೊಂಡಿದೆ, ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಇಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಮಾಧ್ಯಮವಿಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಅಥವಾ ಮಾಧ್ಯಮವಿಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ಮಾಧ್ಯಮ ಆಡಿಯೋ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ಫೋನ್ ಕರೆಗಳು"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ಫೈಲ್ ವರ್ಗಾವಣೆ"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ವೈ-ಫೈನಿಂದ ಮೊಬೈಲ್‌ಗೆ ಆಕ್ರಮಣಕಾರಿ ಹಸ್ತಾಂತರ"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ವೈ-ಫೈ ರೋಮ್ ಸ್ಕ್ಯಾನ್‌ಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ಹಾರ್ಡ್‌ವೇರ್‌ನ ವೇಗವರ್ಧನೆಯನ್ನು ಟೆಥರಿಂಗ್ ಮಾಡಿ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ಸಂಪೂರ್ಣ ವಾಲ್ಯೂಮ್‌ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ಇನ್ ಬ್ಯಾಂಡ್ ರಿಂಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿ"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ಅಣಕು ಸ್ಥಾನಗಳನ್ನು ಅನುಮತಿಸಿ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ವೀಕ್ಷಣೆ ಆಟ್ರಿಬ್ಯೂಟ್ ಪರಿಶೀಲನೆ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ವೈ-ಫೈ ಸಕ್ರಿಯವಾಗಿರುವಾಗಲೂ, ಯಾವಾಗಲೂ ಮೊಬೈಲ್‌ ಡೇಟಾ ಸಕ್ರಿಯವಾಗಿರಿಸಿ (ವೇಗವಾಗಿ ನೆಟ್‌ವರ್ಕ್‌ ಬದಲಾಯಿಸಲು)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ಹಾರ್ಡ್‌ವೇರ್‌ನ ವೇಗವರ್ಧನೆ ಟೆಥರಿಂಗ್ ಲಭ್ಯವಿದ್ದರೆ ಅದನ್ನು ಬಳಸಿ"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ಅಧಿಸೂಚನೆ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ನೀವು ಹಿಂದೆ ಅಧಿಕೃತಗೊಳಿಸಿದ ಎಲ್ಲ ಕಂಪ್ಯೂಟರ್‌ಗಳಿಂದ USB ಡೀಬಗ್‌ಗೆ ಪ್ರವೇಶವನ್ನು ರದ್ದುಗೊಳಿಸುವುದೇ?"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 385172d..b7cf515 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"연결됨(미디어 없음)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"연결됨(메시지 액세스 없음)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"연결됨(전화 또는 미디어 없음)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"연결됨, 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"연결됨(전화 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"연결됨(미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"연결됨(전화 또는 미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"미디어 오디오"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"전화 통화"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"파일 전송"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"적극적인 Wi-Fi-모바일 핸드오버"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi 로밍 스캔 항상 허용"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"항상 모바일 데이터 활성화"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"테더링 하드웨어 가속"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"절대 볼륨 사용 안함"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"대역 내 벨소리 사용 설정"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"블루투스 AVRCP 버전"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"모의 위치 허용"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"보기 속성 검사 사용"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi가 활성화되어 있을 때에도 빠른 네트워크 전환을 위하여 항상 모바일 데이터를 활성 상태로 유지합니다."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"가능한 경우 테더링 하드웨어 가속 사용"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB 디버깅을 허용하시겠습니까?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 디버깅은 개발용으로만 설계되었습니다. 이 기능을 사용하면 컴퓨터와 기기 간에 데이터를 복사하고 알림 없이 기기에 앱을 설치하며 로그 데이터를 읽을 수 있습니다."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"이전에 승인한 모든 컴퓨터에서 USB 디버깅에 대한 액세스 권한을 취소하시겠습니까?"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index a5cee81..1fb4b48 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Туташып турат (медиасыз)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Байланышта (билдирүү алмашуу жок)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Туташып турат (телефониясыз же медиасыз)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Туташып турат, батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Туташып турат (телефониясыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Туташып турат (медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Туташып турат (телефониясыз же медиасыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефон чалуулар"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл алмашуу"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi начар болсо, мобилдик Инт-ке өтсүн"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi Роуминг Скандоо мүмкүнчүлүгүнө ар дайым уруксат берилсин"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилдик Интернет иштей берсин"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетерингдин иштешин тездетүү"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үндүн абсолюттук деңгээли өчүрүлсүн"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Канал аралык чалууну иштетүү"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP версиясы"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Жасалма жайгашкан жерди көрсөтүүгө уруксат берилсин"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Аттрибут текшерүүсүнүн көрүнүшүн иштетүү"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi-Fi иштеп турганда да дайындар мобилдик тармак аркылуу өткөрүлө берсин (тармактар ортосунда тезирээк которулуу үчүн)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Эгер мүмкүн болсо, тетерингдин иштеши тездетилсин"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB аркылуу жөндөөгө уруксат берилсинби?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-жөндөө - өндүрүү максатында гана  түзүлгөн. Аны компүтериңиз менен түзмөгүңүздүн ортосунда берилиштерди алмашуу, түзмөгүңүзгө колдонмолорду эскертүүсүз орнотуу жана лог берилиштерин окуу үчүн колдонсоңуз болот."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Сиз мурун USB жөндөөлөрүнө уруксат берген бардык компүтерлердин жеткиси жокко чыгарылсынбы?"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index ddacdf2..88bdc41 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີສື່)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ເຊື່ອມຕໍ່ (ບໍ່ມີການເຂົ້າເຖິງຂໍ້ຄວາມ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ ຫຼືສື່)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ເຊື່ອມຕໍ່ແລ້ວ, ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີມີເດຍ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ ຫຼື ມີເດຍ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ສຽງ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ການໂທ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ການໂອນຍ້າຍໄຟລ໌"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ສະຫຼັບເປັນ Wi-Fi ເມື່ອມືຖືສັນຍານອ່ອນ"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ອະ​ນຸ​ຍາດ​ການ​ສະ​ແກນ​ການ​ໂຣມ Wi‑Fi ​ສະ​ເໝີ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ເປີດໃຊ້ອິນເຕີເນັດມືຖືຕະຫຼອດເວລາ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ປິດໃຊ້ລະດັບສຽງສົມບູນ"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ເປີດສຽງເຕືອນແບບອິນແບນ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ເວີຊັນ Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ອະນຸຍາດໃຫ້ຈຳລອງຕຳແໜ່ງ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ເປີດ​ນຳ​ໃຊ້​ການກວດ​ສອບ​ຄຸນ​ສົມ​ບັດ​ມຸມມອງ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ໃຫ້​ຂໍ້​ມູນ​ມື​ຖື​ເປີດ​ຢູ່​ສະ​ເໝີ, ແມ້​ແຕ່​ເມື່ອ Wi‑Fi ເປີດ​ຢູ່ (ສຳ​ລັບ​ການ​ສະ​ຫຼັບ​ເຄືອ​ຂ່າຍ​ໄວ)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວຫາກວ່າສາມາດໃຊ້ໄດ້"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"ອະນຸຍາດໃຫ້ດີບັ໊ກຜ່ານ USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"ການດີບັ໊ກຜ່ານ USB ແມ່ນມີຈຸດປະສົງເພື່ອການພັດທະນາເທົ່ານັ້ນ. ມັນສາມາດໃຊ້ເພື່ອສຳເນົາຂໍ້ມູນລະຫວ່າງຄອມພິວເຕີ ແລະອຸປະກອນຂອງທ່ານ, ຕິດຕັ້ງແອັບຯໂດຍບໍ່ຜ່ານການແຈ້ງເຕືອນ ແລະອ່ານຂໍ້ມູນການບັນທຶກ."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ຖອດຖອນການເຂົ້າເຖິງການດີບັ໊ກຜ່ານ USB ຈາກຄອມພິວເຕີທຸກເຄື່ອງ ທີ່ທ່ານເຄີຍອະນຸຍາດກ່ອນໜ້ານີ້?"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 99d2875..8ca0d36 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Prijungta (be laikmenos)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Prisijungta (be prieigos prie pranešimų)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Prijungta (be telefono ar laikmenos)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Prijungta, akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Prijungta (be telefono), akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Prijungta (be medijos), akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Prijungta (be telefono ar medijos), akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Laikmenos garsas"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefono skambučiai"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failo perkėlimas"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. „Wi‑Fi“ perd. į mob. r. tinklą"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Visada leisti „Wi-Fi“ tarptiklinio ryšio nuskaitymą"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiliojo ryšio duomenys visada suaktyvinti"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Įrenginio kaip modemo naudojimo aparatinės įrangos spartinimas"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Išjungti didžiausią garsą"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Įgalinti diapazono skambėjimą"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"„Bluetooth“ AVRCP versija"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Leisti imituoti vietas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Įgalinti peržiūros atributų tikrinimą"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Visada suaktyvinti mobiliojo ryšio duomenis, net kai aktyvus „Wi‑Fi“ ryšys (kad būtų galima greitai perjungti tinklą)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Naudoti įrenginio kaip modemo naudojimo aparatinės įrangos spartinimą, jei pasiekiama"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Leisti USB perkrovimą?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB derinimas skirtas naudoti tik kūrimo tikslais. Jis gali būti naudojamas norint kopijuoti duomenis iš kompiuterio į įrenginį ir atvirkščiai, įdiegti programas įrenginyje be pranešimo ir skaityti žurnalo duomenis."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Panaikinti visų kompiuterių, kuriems anksčiau suteikėte prieigos teisę, prieigą prie USB derinimo?"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 8ade7d4..518eb33 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Sav. ir izveidots (nav multivides)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Savienots (nav piekļuves ziņojumam)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Sav. ir izveidots (nav tel. vai multiv.)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Savienojums izveidots, akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Savienojums izveidots (nav tālrunis), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Savienojums izveidots (nav multivide), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Savienojums izveidots (nav tālrunis vai multivide), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multivides audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Tālruņa zvani"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failu pārsūtīšana"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresīva pāreja no Wi‑Fi uz mobilo tīklu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vienmēr atļaut Wi‑Fi meklēšanu"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Vienmēr aktīvs mobilo datu savienojums"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Paātrināta aparatūras darbība piesaistei"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Atspējot absolūto skaļumu"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Iespējot iekšjoslas zvanīšanu"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versija"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Atļaut neīstas vietas"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Iespējot atribūtu pārbaudi"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobilo datu savienojums būs vienmēr aktīvs, pat ja būs aktīvs Wi-Fi savienojums (ātrai ierīces pārslēgšanai uz citu tīklu)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Izmantot paātrinātu aparatūras darbību piesaistei, ja tā ir pieejama"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Vai atļaut USB atkļūdošanu?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB atkļūdošana ir paredzēta tikai ar izstrādi saistītām darbībām. Izmantojiet to datu kopēšanai no datora uz ierīci un pretēji, lietotņu instalēšanai ierīcē bez paziņojumiem un žurnāla datu lasīšanai."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vai atcelt piekļuvi USB atkļūdošanai no visiem datoriem, kuriem iepriekš piešķīrāt piekļuvi?"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 666cc12..3f7ab8c 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Поврзани (без медиуми)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Поврзано (без порака за пристап)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Поврзан (без телефон или медиуми)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Поврзан, ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Поврзан (освен телефонот), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Поврзан (освен аудио-визуелните содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Поврзан (освен телефонот и аудио-визуелните содржини), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио на медиуми"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонски повици"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Пренос на датотека"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресивно предавање од Wi‑Fi на мобилен"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Секогаш дозволувај Wi‑Fi скенирање во роаминг"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилниот интернет е секогаш активен"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско забрзување за врзување"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Оневозможете апсолутна јачина на звук"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Овозможете ѕвонење во појас"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Овозможи лажни локации"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Овозможете проверка на атрибутот на приказот"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Секогаш држи го активен мобилниот интернет, дури и при активно Wi-Fi (за брзо префрлување мрежа)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Ако е достапно, користете хардверско забрзување за врзување"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Овозможи отстранување грешки на USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отстранувањето грешки на USB е наменето само за целите на развој. Користете го за копирање податоци меѓу вашиот компјутер и вашиот уред, за инсталирање апликации на вашиот уред без известување и за читање евиденција на податоци."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Отповикај пристап кон отстранување грешка од USB од сите претходно овластени компјутери?"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index f657b43..635d8a4 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"കണക്‌റ്റുചെയ്‌തു (മീഡിയ ഇല്ല)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"കണക്റ്റുചെയ്‌തു (സന്ദേശ ആക്‌സസ്സില്ല)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"കണ‌ക്റ്റുചെ‌യ്തു (ഫോണോ മീഡിയയോ അല്ല)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"കണക്‌റ്റുചെയ്‌തു, ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"കണ‌ക്റ്റുചെയ്‌തു (ഫോൺ ഇല്ല), ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"കണക്‌റ്റുചെയ്‌തു (മീഡിയ ഇല്ല), ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"കണ‌ക്റ്റുചെയ്‌തു (ഫോണോ മീഡിയയോ ഇല്ല), ബാറ്ററി നില<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"മീഡിയ ഓഡിയോ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ഫോണ്‍‌ കോളുകൾ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ഫയൽ കൈമാറൽ"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"മൊബൈൽ ഹാൻഡ്ഓവറിലേക്ക് വൈഫൈ സക്രിയമാക്കുക"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"എപ്പോഴും വൈഫൈ റോം സ്‌‌കാൻ അനുവദിക്കൂ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"മൊബൈൽ ഡാറ്റ എല്ലായ്‌പ്പോഴും സജീവം"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ടെതറിംഗ് ഹാർഡ്‌വെയർ ത്വരിതപ്പെടുത്തൽ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"അബ്‌സൊല്യൂട്ട് വോളിയം പ്രവർത്തനരഹിതമാക്കുക"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ഇൻ-ബാൻഡ് റിംഗുചെയ്യൽ പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP പതിപ്പ്"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"വ്യാജ ലൊക്കേഷനുകൾ അനുവദിക്കുക"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ആട്രിബ്യൂട്ട് പരിശോധന കാണൽ സജീവമാക്കൂ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"വൈഫൈ സജീവമാണെങ്കിലും, മൊബൈൽ ഡാറ്റ സജീവമായി നിർത്തുക (വേഗത്തിൽ നെറ്റ്‌വർക്ക് മാറുന്നതിനായി)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ലഭ്യമാണെങ്കിൽ \'ടെതറിംഗ് ഹാർഡ്‌വെയർ ത്വരിതപ്പെടുത്തൽ\' ഉപയോഗിക്കുക"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ഡീബഗ്ഗുചെയ്യാൻ അനുവദിക്കണോ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ഡീബഗ്ഗിംഗ് വികസന ആവശ്യകതകൾക്ക് മാത്രമുള്ളതാണ്. നിങ്ങളുടെ കമ്പ്യൂട്ടറിനും ഉപകരണത്തിനുമിടയിൽ ഡാറ്റ പകർത്തുന്നതിനും അറിയിപ്പില്ലാതെ തന്നെ നിങ്ങളുടെ ഉപകരണത്തിൽ അപ്ലിക്കേഷനുകൾ ഇൻസ്‌റ്റാളുചെയ്യുന്നതിനും ലോഗ് ഡാറ്റ റീഡുചെയ്യുന്നതിനും ഇത് ഉപയോഗിക്കുക."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"നിങ്ങൾ മുമ്പ് അംഗീകരിച്ച എല്ലാ കമ്പ്യൂട്ടറുകളിൽ നിന്നും USB ഡീബഗ്ഗുചെയ്യുന്നതിനുള്ള ആക്‌സസ്സ് പിൻവലിക്കണോ?"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index a0f3cee..1e864da 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Холбогдсон (медиа байхгүй)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Холбогдсон (зурвас хандалт байхгүй)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Холбогдсон (утас буюу медиа байхгүй)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Холбогдсон (утас байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Холбогдсон (медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Холбогдсон (утас эсвэл медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Медиа аудио"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Утасны дуудлага"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл дамжуулалт"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Идэвхтэй Wi‑Fi-с мобайл сүлжээнд"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Роум сканыг байнга зөвшөөрөх"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобайл дата байнга идэвхтэй"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем болгох хардвер хурдасгуур"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үнэмлэхүй дууны түвшинг идэвхгүй болгох"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Сүлжээний хонхны аяыг идэвхжүүлэх"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP хувилбар"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Хуурамч байршлыг зөвшөөрөх"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Харах тохируулгын шалгалтыг идэвхжүүлэх"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi идэвхтэй байхад ч гэсэн гар утасны датаг идэвхтэй байлгадаг (сүлжээг түргэн солихын тулд)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Модем болгох хардвер хурдасгуурыг боломжтой тохиолдолд ашиглах"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB дебаг хийхийг зөвшөөрөх үү?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB дебаг нь зөвхөн хөгжүүлэлтийн зорилготой. Үүнийг өөрийн компьютер болон төхөөрөмжийн хооронд өгөгдөл хуулах, өөрийн төхөөрөмж дээр мэдэгдэлгүйгээр аппликейшн суулгах, лог датаг унших зэрэгт ашиглаж болно."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Таны өмнө нь зөвшөөрөл өгсөн бүх компьютерээс USB дебаг хандалтыг нь хураах уу?"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 0a90722..0d5f90b 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"कनेक्ट केले (मीडिया नाही)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"कनेक्ट केलेले आहे (कोणत्याही संदेशामध्ये प्रवेश नाही)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"कनेक्ट केले (फोन किंवा मीडिया नाही)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"कनेक्ट केलेले आहे, बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"कनेक्ट केलेले आहे (कोणताही फोन नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"कनेक्ट केलेले आहे (कोणताही मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"कनेक्ट केलेले आहे (कोणताही फोन किंवा मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडिओ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानांतरण"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"मोबाइलकडे सोपवण्यासाठी आक्रमक वाय-फाय"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"वाय-फाय रोम स्‍कॅनला नेहमी अनुमती द्या"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा नेहमी सक्रिय"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिंग हार्डवेअर प्रवेग"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"संपूर्ण आवाज अक्षम करा"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"इन-बँड रिंगिंग सक्षम करा"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लूटुथ AVRCP आवृत्ती"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"बनावट स्थानांना अनुमती द्या"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"दृश्‍य विशेषता तपासणी सक्षम करा"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"जरी वाय-फाय सक्रिय असले तरीही, नेहमी मोबाईल डेटा सक्रिय ठेवा (जलद नेटवर्क स्विच करण्यासाठी)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध असल्यास टेदरिंग हार्डवेअर प्रवेग वापरा"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डीबग करण्यास अनुमती द्यायची?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करण्याचा हेतू फक्त विकासाच्या उद्देशांसाठी आहे. याचा वापर आपला संगणक आणि आपले डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय आपल्या डिव्हाइसवर अॅप्स स्थापित करा आणि लॉग डेटा वाचा."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"आपण पूर्वी प्राधिकृत केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी प्रवेश पुनर्प्राप्त करायचा?"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 8aadf7c..caa07f9 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Disambungkan (tiada media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Disambungkan (tiada akses mesej)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Disambungkan (tiada telefon atau media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Disambungkan, bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Disambungkan (tiada telefon), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Disambungkan (tiada media), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Disambungkan (tiada telefon atau media), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Panggilan telefon"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Pemindahan fail"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Penyerahan Wi-Fi ke mudah alih agresif"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sentiasa benarkan Imbasan Perayauan Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Data mudah alih sentiasa aktif"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Pecutan perkakasan penambatan"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Lumpuhkan kelantangan mutlak"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Dayakan dering dalam jalur"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versi AVRCP Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Benarkan lokasi olokan"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Dayakan pemeriksaan atribut paparan"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Pastikan data mudah alih sentiasa aktif, walaupun Wi-Fi aktif (untuk penukaran rangkaian yang pantas)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gunakan pecutan perkakasan penambatan jika tersedia"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Benarkan penyahpepijatan USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Penyahpepijatan USB adalah dimaksudkan untuk tujuan pembangunan sahaja. Gunakannya untuk menyalin data antara komputer dan peranti anda, memasang aplikasi pada peranti anda tanpa pemberitahuan, dan membaca data log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Batalkan akses ke penyahpepijatan USB dari semua komputer yang anda berikan kebenaran sebelum ini?"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 85f89a1..e1f0085 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ချိတ်ဆက်ထားပြီး (မီဒီယာမရှိ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ချိတ်ဆက်မိသည် (သတင်းရယူမှုမရှိ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ချိတ်ဆက်ပြီး (ဖုန်း သို့ မီဒီယာမဟုတ်ပါ)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ချိတ်ဆက်ပြီးပါပြီ၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ချိတ်ဆက်ပြီးပါပြီ (မည်သည့်ဖုန်းမျှ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ချိတ်ဆက်ပြီးပါပြီ (မည်သည့် မီဒီယာမျှ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ချိတ်ဆက်ပြီးပါပြီ (မည်သည့် ဖုန်း သို့မဟုတ် မီဒီယာမျှ မရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"မီဒီယာ အသံ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ဖုန်းခေါ်ဆိုမှုများ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ဖိုင်လွဲပြောင်းခြင်း"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi‑Fi မှ မိုဘိုင်းသို့ လွှဲပြောင်းရန်"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi ရွမ်းရှာဖွေမှုကို အမြဲတမ်း ခွင့်ပြုမည်"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ဖုန်းကို မိုဒမ်အဖြစ်အသုံးပြုမှု စက်ပစ္စည်းဖြင့် အရှိန်မြှင့်တင်ခြင်း"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ပကတိ အသံနှုန်း သတ်မှတ်ချက် ပိတ်ရန်"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"သတ်မှတ်ထားသည့်ဖုန်းမြည်သံကို အသုံးပြုခြင်းအား ဖွင့်ရန်"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ဘလူးတုသ် AVRCP ဗားရှင်း"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ပုံစံတုတည်နေရာများကို ခွင့်ပြုရန်"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"အရည်အချင်းများ စူးစမ်းမှု မြင်ကွင်းကို ဖွင့်ပေးရန်"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ဝိုင်ဖိုင်ဖွင့်ထားလျှင်တောင် မိုဘိုင်းဒေတာအမြဲတမ်းဖွင့်မည် (မြန်ဆန်သည့် ကွန်ရက် ပြောင်းခြင်းအတွက်)။"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ဖုန်းကို မိုဒမ်အဖြစ်သုံးမှု စက်ပစ္စည်းဖြင့် အရှိမြှင့်တင်ခြင်းကို ရနိုင်လျှင် သုံးရန်"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ပြသနာရှာခြင်း ခွင့်ပြုပါမလား?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USBအမှားရှားခြင်းမှာ ဆော့ဝဲလ်ရေးသားရန်အတွက်သာ ရည်ရွယ်ပါသည်။ သင့်ကွန်ပြုတာနှင့်သင့်စက်ကြားတွင် ဒေတာများကိုကူးယူရန်၊ အကြောင်းမကြားပဲနှင့် သင့်စက်အတွင်းသို့ အပလီကေးရှင်းများထည့်သွင်းခြင်းနှင့် ဒေတာမှတ်တမ်းများဖတ်ရန်အတွက် အသုံးပြုပါ"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"သင် ယခင်က ခွင့်ပြုခဲ့သော ကွန်ပျူတာအားလုံးမှ ယူအက်စ်ဘီ အမှားစစ်ခွင့်ကို ရုတ်သိမ်းမည်လား ?"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 7cb6816..004fcf1e 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Tilkoblet (ingen medier)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Tilkoblet (ingen meldingstilgang)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Tilkoblet (ingen telefon eller media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Tilkoblet, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Tilkoblet (ingen telefon), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Tilkoblet (ingen medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Tilkoblet (ingen telefon eller medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonsamtaler"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverføring"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv overføring fra Wi-Fi til mobil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillat alltid skanning for Wi-Fi-roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er alltid aktiv"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvareakselerasjon for internettdeling"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slå av funksjonen for absolutt volum"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Slå på innenbåndsringing"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP-versjon"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Tillat bruk av simulerte GPS-koordinater"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Slå på inspeksjon av visningsattributt"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Ha alltid mobildata slått på, selv når Wi-Fi er aktiv (for hurtig nettverksbytting)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Bruk maskinvareakselerasjon for internettdeling hvis det er tilgjengelig"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Tillate USB-feilsøking?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-feilsøking er bare ment for utviklingsformål. Bruk det til å kopiere data mellom datamaskinen og enheten, installere apper på enheten uten varsel og lese loggdata."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vil du oppheve tilgangen til USB-feilsøking fra alle datamaskiner du tidligere har autorisert?"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 5abcf19..eac1e24 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"जडित (कुनै पनि मिडिया छैन)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"जडित छ (सन्देशमा पहुँच छैन)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"जडित (फोन वा मिडिया छैन)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"यन्त्र जडान भयो, ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"यन्त्र जडान भयो (फोनको अडियो छैन), ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"यन्त्र जडान भयो (मिडियाको अडियो छैन), ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"यन्त्र जडान भयो (फोन वा मिडियाको अडियो छैन), ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मिडिया अडियो"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कलहरू"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानान्तरण"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"आक्रामक ढंगले Wi‑Fi बाट मोबाइलमा हस्तान्तरण"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi घुम्ने स्क्यान गर्न सधैँ अनुमति दिनुहोस्"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"निरपेक्ष आवाज असक्षम गर्नुहोस्"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"इन-ब्यान्ड घन्टी बज्ने सुविधालाई सक्षम पार्नुहोस्"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ब्लुटुथको AVRCP संस्करण"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"नक्कली स्थानहरूलाई अनुमति दिनुहोस्"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"दृष्टिकोण विशेषता निरीक्षण सक्षम पार्नुहोस्"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi-Fi सक्रिय हुँदा पनि मोबाइल डेटा सधैँ सक्रिय राख्नुहोस् (द्रूत नेटवर्क स्विच गर्नको लागि)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध भएमा टेदरिङको लागि हार्डवेयरको प्रवेग प्रयोग गर्नुहोस्"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डिबग गर्न लागि अनुमति दिने हो?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"युएसबी डिबगिङ विकास प्रयोजनका लागि मात्र निर्मित हुन्छ। यसलाई तपाईँको कम्प्युटर र तपाईँको उपकरणका बीच डेटा प्रतिलिपि गर्न, बिना सूचना तपाईँको उपकरणमा अनुप्रयोगहरू स्थापना गर्न र लग डेटा पढ्नका लागि प्रयोग गर्नुहोस्।"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"तपाईं पहिले नै अधिकृत गर्नुभएका सबै कम्प्यूटरबाट USB डिबग गर्नको लागि पहुँच रद्द गर्ने हो?"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 2649a4f..9ca3bfd 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Gekoppeld (geen media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Verbonden (geen toegang tot berichten)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Gekoppeld (geen telefoon of media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Verbonden, batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Verbonden (geen telefoon), batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Verbonden (geen media), batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Verbonden (geen telefoon of media), batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefoongesprekken"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Bestandsoverdracht"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agressieve handover van wifi naar mobiel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Altijd roamingscans voor wifi toestaan"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data altijd actief"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareversnelling voor tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Absoluut volume uitschakelen"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"In-band bellen inschakelen"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth-AVRCP-versie"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Neplocaties toestaan"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspectie van weergavekenmerk inschakelen"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobiele gegevens altijd actief houden, ook als wifi actief is (voor sneller schakelen tussen netwerken)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Hardwareversnelling voor tethering gebruiken indien beschikbaar"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB-foutopsporing toestaan?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-foutopsporing is alleen bedoeld voor ontwikkeldoeleinden. Het kan worden gebruikt om gegevens te kopiëren tussen je computer en je apparaat, apps zonder melding op je apparaat te installeren en loggegevens te lezen."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Toegang tot USB-foutopsporing intrekken voor alle computers waarvoor je dit eerder hebt toegestaan?"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 77ba3f8..084b9ed 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਸੁਨੇਹਾ ਪਹੁੰਚ ਨਹੀਂ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ, ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ (ਕੋਈ ਫ਼ੋਨ ਨਹੀਂ), ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ (ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ), ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ (ਕੋਈ ਫ਼ੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ), ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ਮੀਡੀਆ ਔਡੀਓ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ਫ਼ੋਨ ਕਾਲਾਂ"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ"</string>
@@ -73,8 +69,8 @@
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਸ਼ੇਅਰਿੰਗ"</string>
     <string name="bluetooth_profile_map" msgid="1019763341565580450">"ਲਿਖਤ ਸੁਨੇਹੇ"</string>
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ਪਹੁੰਚ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ਔਡੀਓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ਔਡੀਓ"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ਆਡੀਓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ਆਡੀਓ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ਮੀਡੀਆ ਔਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ਫੋਨ ਔਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ਆਕਰਮਣਸ਼ੀਲ Wi‑Fi ਤੋਂ ਮੋਬਾਈਲ ਹੈਂਡਓਵਰ"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ਹਮੇਸ਼ਾਂ Wi‑Fi Roam Scans ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡੈਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੇਲਰੇਸ਼ਨ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ਪੂਰਨ ਵੌਲਿਊਮ ਨੂੰ ਅਯੋਗ ਬਣਾਓ"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ਇਨ-ਬੈਂਡ ਘੰਟੀ ਵੱਜਣ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ਬਲੂਟੁੱਥ AVRCP ਰੂਪ"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ਨਕਲੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"ਗੁਣ ਛਾਣਬੀਣ ਦੇਖੋ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ਹਮੇਸ਼ਾ ਮੋਬਾਈਲ ਡੇਟਾ ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਰੱਖੋ ਭਾਵੇਂ Wi‑Fi ਕਿਰਿਆਸ਼ੀਲ ਹੋਵੇ (ਤੇਜ਼ ਨੈੱਟਵਰਕ ਸਵਿੱਚਿੰਗ ਲਈ)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ਉਪਲਬਧ ਹੋਣ \'ਤੇ ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੇਲਰੇਸ਼ਨ ਵਰਤੋ"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"ਕੀ USB ਡੀਬਗਿੰਗ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ਡੀਬਗਿੰਗ ਕੇਵਲ ਵਿਕਾਸ ਮੰਤਵਾਂ ਲਈ ਹੁੰਦੀ ਹੈ। ਇਸਨੂੰ ਆਪਣੇ ਕੰਪਿਊਟਰ ਅਤੇ ਆਪਣੀ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਡੈਟਾ ਕਾਪੀ ਕਰਨ ਲਈ ਵਰਤੋ, ਸੂਚਨਾ ਦੇ ਬਿਨਾਂ ਆਪਣੀ ਡੀਵਾਈਸ ਤੇ ਐਪਸ ਇੰਸਟੌਲ ਕਰੋ ਅਤੇ ਲੌਗ ਡੈਟਾ ਪੜ੍ਹੋ।"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ਕੀ ਉਹਨਾਂ ਸਾਰੇ ਕੰਪਿਊਟਰਾਂ ਤੋਂ USB ਡੀਬਗਿੰਗ ਤੱਕ ਪਹੁੰਚ ਰੱਦ ਕਰਨੀ ਹੈ, ਜਿਹਨਾਂ ਲਈ ਪਹਿਲਾਂ ਤੁਸੀਂ ਅਧਿਕਾਰਤ ਕੀਤਾ ਹੈ?"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index b216ff1..58454b4 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Połączono (bez multimediów)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Połączono (brak dostępu do wiadomości)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Połączono (bez telefonu ani multimediów)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Połączono, bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Połączono (bez telefonu), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Połączono (bez multimediów), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Połączono (bez telefonu i multimediów), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Dźwięk multimediów"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Połączenia telefoniczne"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Przesyłanie pliku"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Przełączaj z Wi-Fi na sieć komórkową"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Zawsze szukaj Wi-Fi w roamingu"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna transmisja danych zawsze aktywna"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akceleracja sprzętowa tetheringu"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Wyłącz głośność bezwzględną"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Włącz dzwonek w kanale dźwiękowym"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Wersja AVRCP Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Zezwalaj na pozorowanie lokalizacji"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Inspekcja wyświetlania atrybutu"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Nie wyłączaj transmisji danych przez sieć komórkową, nawet gdy aktywne jest połączenie Wi-Fi (aby szybko przełączać sieci)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Użyj akceleracji sprzętowej tetheringu, jeśli jest dostępna"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Czy zezwalać na debugowanie USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Debugowanie USB jest przeznaczone wyłącznie do celów programistycznych. Może służyć do kopiowania danych między komputerem a urządzeniem, instalowania aplikacji na urządzeniu bez powiadamiania, a także odczytu danych dziennika."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Odwołać dostęp wszystkich poprzednio autoryzowanych komputerów do debugowania USB?"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index d98570f..3b97a7f 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sem mídia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sem acesso a mensagens)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sem telefone ou mídia)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado (sem smartphone), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado (sem mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado (sem smartphone ou mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefônicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência de arquivo"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ativar o toque em banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir locais fictícios"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ativar visualiz. insp. atributo"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Sempre manter dados móveis ativos, mesmo quando o Wi-Fi estiver ativado (para troca rápida de rede)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar aceleração de hardware de tethering quando disponível"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Permitir a depuração USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revogar o acesso à depuração USB para todos os computadores autorizados?"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index dc1aeac..e2c6b2f 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ligado (sem multimédia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ligado (sem acesso a mensagens)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ligado (sem telefone ou multimédia)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ligado com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ligado (sem telemóvel) com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ligado (sem multimédia) com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ligado (sem telemóvel nem multimédia) com <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio de multimédia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência do ficheiro"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança brusca de Wi‑Fi para rede móvel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre a deteção de Wi-Fi em roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware para ligação (à Internet) via telemóvel"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ativar toque dentro da banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão de Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir locais fictícios"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ativar a inspeção do atributo de visualização"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Manter sempre os dados móveis ativados, mesmo quando o Wi‑Fi estiver ativado (para mudança de rede rápida)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Se disponível, utilizar a aceleração de hardware para ligação (à Internet) via telemóvel"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Permitir depuração USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuração USB é utilizada apenas para fins de programação. Utilize-a para copiar dados entre o computador e o aparelho, instalar aplicações no aparelho sem notificação e ler dados de registo."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revogar acesso à depuração USB de todos os computadores anteriormente autorizados?"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index d98570f..3b97a7f 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sem mídia)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sem acesso a mensagens)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sem telefone ou mídia)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectado (sem smartphone), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectado (sem mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectado (sem smartphone ou mídia), nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Chamadas telefônicas"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência de arquivo"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mudança agressiva de Wi-Fi para móvel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Ativar o toque em banda"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versão do Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Permitir locais fictícios"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Ativar visualiz. insp. atributo"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Sempre manter dados móveis ativos, mesmo quando o Wi-Fi estiver ativado (para troca rápida de rede)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Usar aceleração de hardware de tethering quando disponível"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Permitir a depuração USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revogar o acesso à depuração USB para todos os computadores autorizados?"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 23bc4f7..a3a2b47 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectat (fără conținut media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectat (fără acces la mesaje)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectat (fără telefon sau conț. media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Conectat, bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Conectat (fără telefon), bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Conectat (fără conținut media), bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Conectat (fără telefon sau conținut media), bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Conținut media audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Apeluri telefonice"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer de fișiere"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Predare agresivă de la Wi-Fi la mobilă"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Se permite întotdeauna scanarea traficului Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Date mobile permanent active"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accelerare hardware pentru tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Dezactivați volumul absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Activați soneria în căști"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versiunea AVRCP pentru Bluetooth"</string>
@@ -221,6 +218,7 @@
     <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="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>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Folosiți accelerarea hardware pentru tethering, dacă este disponibilă"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Permiteți depanarea USB?"</string>
     <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>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index e5fe5f7..905195a 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Подключено (кроме A2DP)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Подключено (нет доступа к сообщениям)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Подключено (кроме HSP/HFP/A2DP)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Подключено, уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Подключено (кроме звонков), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Подключено (кроме аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Подключено (кроме звонков и аудио), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Профиль A2DP"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Звонки"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Профиль OPP"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Переключаться на мобильную сеть"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Всегда включать поиск сетей Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Аппаратное ускорение в режиме модема"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Отключить абсолютный уровень громкости"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Включить внутриполосное воспроизведение"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версия Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Разрешить использование фиктивных местоположений"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Включить проверку атрибутов"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Не отключать передачу данных по мобильной сети даже при активном Wi-Fi-подключении (для быстрого переключения между сетями)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Использовать аппаратное ускорение в режиме модема (если доступно)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Разрешить отладку по USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отладка по USB – это режим, который позволяет использовать ваше устройство как внешний накопитель: перемещать файлы (с компьютера и на компьютер), напрямую устанавливать приложения, а также просматривать системные журналы."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Запретить доступ к USB-отладке для всех компьютеров, которым он был разрешен?"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 9fc96d5..9c75355 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"සම්බන්ධිතයි (මාධ්‍යයක් නොමැත)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"සම්බන්ධිතයි (පණිවිඩ ප්‍රවේශ නොමැත)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"සම්බන්ධිතයි (දුරකතනයක් හෝ මාධ්‍යයක් නැත)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"සම්බන්ධිතයි, බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"සම්බන්ධිතයි (දුරකථනය නැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"සම්බන්ධිතයි (මාධ්‍යයක් නොමැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"සම්බන්ධිතයි (දුරකථනයක් හෝ මාධ්‍යයක් නැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"මාධ්‍ය ශ්‍රව්‍ය"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"දුරකථන ඇමතුම්"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ගොනු හුවමාරුව"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ආක්‍රමණික Wi‑Fi සිට ජංගම බාර දීම"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi රෝම් පරිලෝකන වෙතට සැමවිට අවසර දෙන්න"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ජංගම දත්ත සැමවිට ක්‍රියාකාරීය"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ටෙදරින් දෘඪාංග ත්වරණය"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"නිරපේක්ෂ හඩ පරිමාව අබල කරන්න"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"කලාපය තුළ නාද වීම සබල කරන්න"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"බ්ලූටූත් AVRCP අනුවාදය"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"ව්‍යාජ ස්ථාන අනුමත කරන්න"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"උපලක්ෂණ පරික්ෂාව බැලීම සබල කරන්න"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi‑Fi අක්‍රිය විට පවා, සැම විටම ජංගම දත්ත ක්‍රියාකාරීව තබන්න (අවසන් ජාල මාරුව සඳහා)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ලබා ගත හැකි නම්, ටෙදරින් දෘඪාංග ත්වරණය භාවිත කරන්න"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB දෝශාවේක්ෂණයට ඉඩ දෙන්නද?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB දෝශාවේක්ෂණය සංවර්ධන කටයුතු සඳහා පමණක් යොදාගැනේ. එය ඔබගේ පරිගණකය සහ ඔබගේ උපාංගය අතර දත්ත පිටපත් කිරීමට පමණක් භාවිතා කරන්න, ඔබගේ උපාංගය මත දැනුම්දීම් රහිතව යෙදුම් ස්ථාපනය කරන්න, සහ ලොග් දත්ත කියවන්න."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ඔබ මින්පෙර අවසර ලබාදුන් සියළුම පරිගණක වෙතින් USB නිදොස්කරණට ප්‍රවේශය අහෝසි කරන්නද?"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index fba2edc..595fd4c 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Pripojené (bez média)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Pripojené (bez prístupu ku správam)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Pripojené (bez telefónu alebo média)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Pripojené, stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Pripojené (žiadny telefón), stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Pripojené (žiadne médiá), stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Pripojené (žiadny telefón ani médiá), stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medií"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonické hovory"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos súborov"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agres. odovzdávať Wi-Fi na mobilnú sieť"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povoliť funkciu Wi-Fi Roam Scans"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilné dáta ponechať vždy aktívne"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardvérovú akcelerácia pre tethering"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázať absolútnu hlasitosť"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Povoliť zvonenie v hovorovom pásme"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Verzia rozhrania Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Povoliť simulované polohy"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Kontrola atribútov zobrazenia"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Vždy ponechávať mobilné dáta aktívne, dokonca aj pri aktívnej sieti Wi‑Fi (na rýchle prepínanie sietí)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Používať hardvérovú akceleráciu pre tethering (ak je k dispozícii)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Povoliť ladenie cez USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ladenie cez USB je určené iba na účely vývoja. Možno ho použiť na kopírovanie dát medzi počítačom a zariadením, inštaláciu aplikácií do zariadenia bez upozornenia a čítanie dát denníka."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Chcete všetkým v minulosti autorizovaným počítačom odvolať prístup k ladeniu cez USB?"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a206c30..b8a0514 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Povezava vzpostavljena (brez predstavnosti)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezava vzp. (ni dostopa do sporočil)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezava vzpostavljena (brez telefona ali predstavnosti)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Povezava je vzpostavljena, raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Povezava je vzpostavljena (brez telefona), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Povezava je vzpostavljena (brez predstavnosti), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Povezava je vzpostavljena (brez telefona ali predstavnosti), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvok predstavnosti"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonski klici"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos datoteke"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Odločen prehod iz Wi-Fi-ja v mobil. omr."</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vedno omogoči iskanje omrežij Wi-Fi za gostovanje"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Strojno pospeševanje za internetno povezavo prek mobilnega telefona"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogočanje absolutnega praga glasnosti"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Omogoči zvonjenje iz telefona"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Različica profila AVRCP za Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Dovoli lažne lokacije"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Omogoči pregled atributa pogleda"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Prenos podatkov v mobilnih omrežjih je vedno aktiven – tudi ko je aktivna povezava Wi-Fi (za hiter preklop med omrežji)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Uporabi strojno pospeševanje za internetno povezavo prek mobilnega telefona, če je na voljo"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Ali dovolite odpravljanje težav s povezavo USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Odpravljanje težav s povezavo USB je namenjeno samo za razvoj. Lahko ga uporabljate za kopiranje podatkov med računalnikom in napravo, nameščanje aplikacij v napravo brez obveščanja in branje podatkov v dnevniku."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Ali želite preklicati dostop do odpravljanja težav prek povezave USB iz vseh računalnikov, ki ste jih pooblastili?"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index c3ad1f2..34d0333 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"U lidh (nuk ka media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"U lidh (pa qasje te mesazhet)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"I lidhur (pa telefon apo media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"E lidhur, bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"E lidhur (nuk ka telefon), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"E lidhur (nuk ka media), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"E lidhur (nuk ka telefon ose media), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audioja e klipit \"media\""</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonatat"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferimi i skedarëve"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Dorëzimi agresiv i Wi‑Fi te rrjeti celular"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Lejo gjithmonë skanimet për Wi-Fi edhe kur je në lëvizje"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Të dhënat celulare gjithmonë aktive"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Përshpejtimi i harduerit për ndarjen"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Çaktivizo volumin absolut"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktivizo zilen brenda të njëjtit brez"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Versioni AVRCP i Bluetooth-it"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Lejo vendndodhje të simuluara"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktivizo shikimin e inspektimit të atributeve"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mbaji të dhënat celulare gjithmonë aktive edhe kur Wi‑Fi është aktiv (për ndërrim të shpejtë të rrjetit)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Përdor përshpejtimin e harduerit për ndarjen nëse është i disponueshëm"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Të lejohet korrigjimi i USB-së?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Korrigjuesi i USB-së është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes tënde, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e ditarit."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Të bllokohet qasja për korrigjim të USB-së nga të gjithë kompjuterët që ke autorizuar më parë?"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index aa8387b..2b21d30 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Повезано (без медија)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Повезано је (нема приступа порукама)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Повезано (без телефона или медија)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Повезано (без телефона), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Повезано (без медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Повезано (без телефона или медија), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медија"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонски позиви"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Пренос датотеке"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Агресиван прелаз са Wi‑Fi мреже на мобилну"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Увек дозволи скенирање Wi‑Fi-ја у ромингу"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилни подаци су увек активни"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско убрзање привезивања"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Онемогући главно подешавање јачине звука"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Омогућавање звоњаве на истом каналу"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Верзија Bluetooth AVRCP-а"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Дозволи лажне локације"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Омогући проверу атрибута за преглед"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Нека мобилни подаци увек буду активни, чак и када је Wi‑Fi активан (ради брзе промене мреже)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Користи хардверско убрзање привезивања ако је доступно"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Дозволи отклањање USB грешака?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отклањање USB грешака намењено је само за сврхе програмирања. Користите га за копирање података са рачунара на уређај и обрнуто, инсталирање апликација на уређају без обавештења и читање података из евиденције."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Желите ли да опозовете приступ отклањању USB грешака са свих рачунара које сте претходно одобрили?"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index deaa6ae..d73ec66 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ansluten (inga media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ansluten (ingen meddelandeåtkomst)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ansluten (ingen telefon och inga media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ansluten, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ansluten (ingen mobil), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ansluten (inga medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ansluten (ingen mobil och inga medier), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medialjud"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonsamtal"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filöverföring"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressiv överlämning fr. Wi-Fi t. mobil"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillåt alltid sökning efter Wi-Fi-roaming"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata alltid aktiverad"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvaruacceleration för internetdelning"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inaktivera Absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Aktivera samtal inom nätverket"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"AVRCP-version för Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Tillåt skenplatser"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Aktivera inspektion av visningsattribut"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Håll alltid mobildata aktiverad, även när Wi-Fi är aktiverat (så att du snabbt kan byta mellan nätverk)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Använd maskinvaruacceleration för internetdelning om tillgängligt"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Ska USB-felsökning tillåtas?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB-felsökning ska endast användas i utvecklingssyfte. Använd den för att kopiera data mellan datorn och enheten, installera appar på enheten utan meddelanden och läsa loggdata."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vill du återkalla åtkomst till USB-felsökning för alla datorer som du tidigare har godkänt?"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 3582f50..e1fc468 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Imeunganishwa(hakuna vyombo vya habari)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Imeunganishwa (hakuna ufikiaji kwa ujumbe)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Imeunganishwa(hakuna simu au vyombo vya habari)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Imeunganishwa, kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Imeunganishwa (hakuna simu), kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Imeunganishwa (hakuna maudhui), kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Imeunganishwa (hakuna simu wala maudhui), kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media ya sauti"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Simu"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Uhamishaji wa faili"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukabidhi hima kutoka Wifi kwenda mtandao wa simu"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Ruhusu Uchanganuzi wa Matumizi ya Mitandao mingine"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Iendelee kutumia data ya simu"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zima sauti kamili"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Washa kipengele cha mlio wa simu katika kituo hicho hicho"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Toleo la Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Ruhusu maeneo ya majaribio"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Washa ukaguzi wa sifa ya onyesho"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Washa kila wakati data ya kifaa cha mkononi, hata kama Wi-Fi inatumika (katika uzimaji wa haraka wa mtandao)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Tumia huduma ya kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao ikiwa inapatikana"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Ruhusu utatuaji USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ueuaji wa USB umekusudiwa kwa malengo ya utengenezaji tu. Itumi kunakili data kati ya kompyuta yako na kifaa chako, kusanidi programu kwa kifaa chako bila arifa, na kusoma data ya rajisi."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Unataka kubatilisha ufikiaji wa urekebishaji wa USB kutoka kwenye kompyuta zote ulizotangulia kuidhinisha?"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 2eca4d7..b16a29c 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"இணைக்கப்பட்டது (மீடியா இல்லை)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"இணைக்கப்பட்டது (செய்திக்கான அணுகல் இல்லை)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"இணைக்கப்பட்டது (மொபைல் அல்லது மீடியாவுடன் அல்ல)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"இணைக்கப்பட்டது, பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"இணைக்கப்பட்டது (மொபைல் ஆடியோ இணைக்கப்படவில்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"இணைக்கப்பட்டது (மீடியா ஆடியோ இணைக்கப்படவில்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"இணைக்கப்பட்டது (மொபைல் அல்லது மீடியா ஆடியோ இணைக்கப்படவில்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"மீடியா ஆடியோ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ஃபோன் அழைப்புகள்"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"கோப்பு இடமாற்றம்"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ஒத்துழைக்காத வைஃபையிலிருந்து மொபைல் தரவிற்கு மாறு"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"எப்போதும் வைஃபை ரோமிங் ஸ்கேன்களை அனுமதி"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"மொபைல் தரவை எப்போதும் இயக்கத்திலேயே வை"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"அப்சல்யூட் ஒலியளவு அம்சத்தை முடக்கு"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"இன்-பேண்ட் ரிங் செய்வதை இயக்கு"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"புளூடூத் AVRCP பதிப்பு"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"போலி இருப்பிடங்களை அனுமதி"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"காட்சி பண்புக்கூறு சோதனையை இயக்கு"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"வைஃபை இயங்கும் போதும் (வேகமான நெட்வொர்க் மாற்றத்திற்கு), மொபைல் தரவை எப்போதும் இயக்கத்தில் வைக்கும்."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை கிடைக்கும் போது, அதைப் பயன்படுத்தும்"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB பிழைத்திருத்தத்தை அனுமதிக்கவா?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB பிழைத்திருத்தம் மேம்படுத்தல் நோக்கங்களுக்காக மட்டுமே. அதை உங்கள் கணினி மற்றும் சாதனத்திற்கு இடையில் தரவை நகலெடுக்கவும், அறிவிப்பு இல்லாமல் உங்கள் சாதனத்தில் பயன்பாடுகளை நிறுவவும், பதிவு தரவைப் படிக்கவும் பயன்படுத்தவும்."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"நீங்கள் ஏற்கனவே அனுமதித்த எல்லா கணினிகளிலிருந்தும் USB பிழைத்திருத்தத்திற்கான அணுகலைத் திரும்பப்பெற வேண்டுமா?"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index b7936fc..921af68 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"కనెక్ట్ చేయబడింది (మీడియా కాదు)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"కనెక్ట్ చేయబడింది (సందేశ ప్రాప్యత లేదు)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"కనెక్ట్ చేయబడింది (ఫోన్ లేదా మీడియా కాకుండా)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"కనెక్ట్ చేయబడింది, బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"కనెక్ట్ చేయబడింది (ఫోన్ కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"కనెక్ట్ చేయబడింది (మీడియా కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"కనెక్ట్ చేయబడింది (ఫోన్ లేదా మీడియా కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"మీడియా ఆడియో"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ఫోన్ కాల్‌లు"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ఫైల్ బదిలీ"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"మొబైల్‌కి మార్చేలా చురుకైన Wi‑Fi"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi సంచార స్కాన్‌లను ఎల్లప్పుడూ అనుమతించు"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"మొబైల్ డేటాని ఎల్లప్పుడూ సక్రియంగా ఉంచు"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"టీథెరింగ్ హార్డ్‌వేర్ వేగవృద్ధి"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"సంపూర్ణ వాల్యూమ్‌‍ను నిలిపివేయి"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ఇన్-బ్యాండ్ రింగింగ్‌ని ప్రారంభించండి"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"బ్లూటూత్ AVRCP సంస్కరణ"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"అనుకృత స్థానాలను అనుమతించు"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"వీక్షణ లక్షణ పర్యవేక్షణను ప్రారంభించు"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ఎల్లప్పుడూ మొబైల్ డేటాను సక్రియంగా ఉంచు, Wi‑Fi సక్రియంగా ఉన్నా కూడా (వేగవంతమైన నెట్‌వర్క్ మార్పు కోసం)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"అందుబాటులో ఉంటే టీథెరింగ్ హార్డ్‌వేర్ వేగవృద్ధిని ఉపయోగించండి"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB డీబగ్గింగ్ అనేది అభివృద్ధి ప్రయోజనాల కోసం మాత్రమే ఉద్దేశించబడింది. మీ కంప్యూటర్ మరియు మీ పరికరం మధ్య డేటాను కాపీ చేయడానికి, నోటిఫికేషన్ లేకుండా మీ పరికరంలో అనువర్తనాలను ఇన్‌స్టాల్ చేయడానికి మరియు లాగ్ డేటాను చదవడానికి దీన్ని ఉపయోగించండి."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"మీరు గతంలో ప్రామాణీకరించిన అన్ని కంప్యూటర్‌ల నుండి USB డీబగ్గింగ్‌కు ప్రాప్యతను ఉపసంహరించాలా?"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 4631e85..4f31238 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -55,16 +55,12 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"เชื่อมต่อแล้ว (ยกเว้นเสียงสื่อ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"เชื่อมต่อแล้ว (ไม่มีการเข้าถึงข้อความ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"เชื่อมต่อ (ยกเว้นเสียงโทรศัพท์หรือสื่อ)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
-    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"เสียงสื่อ"</string>
-    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"การโทรศัพท์"</string>
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"เชื่อมต่ออยู่ แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"เชื่อมต่ออยู่ (ไม่มีโทรศัพท์) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"เชื่อมต่ออยู่ (ไม่มีสื่อ) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"เชื่อมต่ออยู่ (ไม่มีโทรศัพท์หรือสื่อ) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"เสียงของสื่อ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"โทรศัพท์"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"การถ่ายโอนไฟล์"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"อุปกรณ์อินพุต"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"การเข้าถึงอินเทอร์เน็ต"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"สลับ Wi‑Fi เป็นมือถือเมื่อสัญญาณอ่อน"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ใช้การสแกน Wi-Fi ข้ามเครือข่ายเสมอ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"เปิดใช้อินเทอร์เน็ตมือถือเสมอ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ปิดใช้การควบคุมระดับเสียงของอุปกรณ์อื่น"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"เปิดใช้การส่งเสียงในช่องสัญญาณเดียวกัน"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"เวอร์ชันของบลูทูธ AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"อนุญาตให้จำลองตำแหน่ง"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"เปิดใช้การตรวจสอบแอตทริบิวต์มุมมอง"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"เปิดใช้ข้อมูลมือถืออยู่เสมอ แม้ในเวลาที่ใช้งาน Wi-Fi อยู่ (สำหรับสวิตชิงเครือข่ายความเร็วสูง)"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ใช้การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ หากมี"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"อนุญาตให้แก้ไขข้อบกพร่อง USB หรือไม่"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"การแก้ไขข้อบกพร่อง USB มีไว้เพื่อการพัฒนาเท่านั้น ให้ใช้การแก้ไขนี้เพื่อคัดลอกข้อมูลระหว่างคอมพิวเตอร์และอุปกรณ์ ติดตั้งแอปพลิเคชันบนอุปกรณ์โดยไม่มีการแจ้งเตือน และอ่านข้อมูลบันทึก"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"ยกเลิกการเข้าถึงเพื่อแก้ปัญหาผ่าน USB จากคอมพิวเตอร์ทุกเครื่องที่คุณได้ให้สิทธิ์ก่อนหน้านี้ไหม"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 88b9232..984030d 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Nakakonekta (walang media)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Nakakonekta (walang access sa mensahe)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Nakakonekta (walang telepono o media)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Nakakonekta, baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Nakakonekta (walang telepono), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Nakakonekta (walang media), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Nakakonekta (walang telepono o media), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio ng media"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Mga tawag sa telepono"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Paglilipat ng file"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Agresibong paglipat ng Wi‑Fi sa mobile"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Palaging payagan ang Mga Pag-scan sa Roaming ng Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Palaging aktibo ang mobile data"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardware acceleration para sa pag-tether"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"I-disable ang absolute volume"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"I-enable ang pag-ring na nasa band"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bersyon ng AVRCP ng Bluetooth"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Payagan ang mga kunwaring lokasyon"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"I-enable ang pagsisiyasat sa attribute na view"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Palaging panatilihing aktibo ang mobile data, kahit na aktibo ang Wi‑Fi (para sa mabilis na paglipat ng network)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Gamitin ang hardware acceleration para sa pag-tether kung available"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Payagan ang pag-debug ng USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ang pag-debug ng USB ay para lang sa mga layuning pag-develop. Gamitin ito upang kumopya ng data sa pagitan ng iyong computer at iyong device, mag-install ng mga app sa iyong device nang walang notification, at magbasa ng data ng log."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Bawiin ang access sa pag-debug ng USB mula sa lahat ng computer na dati mong pinahintulutan?"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 2c8e1ec..b0c60f5 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Bağlandı (medya yok)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Bağlı (mesaj erişimi yok)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Bağlandı (telefon veya medya yok)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Bağlandı, pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Bağlandı (telefon yok), pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Bağlandı (medya yok), pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Bağlandı (telefon veya medya yok), pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medya sesi"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon çağrıları"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dosya aktarımı"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Kablosuzdan mobil ağa agresif geçiş"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Kablosuz Dolaşım Taramalarına daima izin ver"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil veri her zaman etkin"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering donanım hızlandırıcısı"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mutlak sesi iptal et"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Bant içi zil çaldırmayı etkinleştir"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Sürümü"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Sahte konumlara izin ver"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Görünüm özelliği incelemeyi etkinleştir"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Kablosuz bağlantı etkin bile olsa mobil veri kullanımını her zaman etkin tut (ağlar arasında hızlı geçiş yapmak için)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Mevcutsa, tethering donanım hızlandırıcısını kullan"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB hata ayıklamasına izin verilsin mi?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB hata ayıklaması yalnızca geliştirme amaçlıdır. Verileri bilgisayarınızla cihazınız arasında kopyalamak, bildirim göndermeksizin uygulamaları cihazınıza yüklemek ve günlük verilerini okumak için kullanın."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Daha önce yetki verdiğiniz tüm bilgisayarların USB hata ayıklama erişimini iptal etmek istiyor musunuz?"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index e7bd0c8..0834d04 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Під’єднано (без медіа-файлів)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Під’єднано (без доступу до повідомлень)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Під’єднано (без телефону чи медіа)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Під’єдано, заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Під’єднано (без телефона), заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Під’єднано (без медіа-вмісту), заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Під’єднано (без телефона та медіа-вмісту), заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медіа-файлів"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Телефонні дзвінки"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Передавання файлів"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Перемикатися з Wi-Fi на мобільну мережу"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Завжди шукати мережі Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не вимикати мобільне передавання даних"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратне прискорення під час використання телефона в режимі модема"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Вимкнути абсолютну гучність"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Увімкнути внутрішньосмугові сигнали"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Дозв. фіктивні місцезн."</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Увімкнути оцінку атрибуції переглядів"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Не вимикати мобільний Інтернет, навіть якщо ввімкнено Wi‑Fi (щоб швидше переходити між мережами)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Якщо доступно, вмикати апаратне прискорення під час використання телефона в режимі модема"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Дозвол. налагодж. USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Налагодження USB застосовується лише з метою розробки. Його можна використовувати для копіювання даних між комп’ютером і пристроєм, встановлення програм на вашому пристрої без сповіщення та читання даних журналу."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Скасувати доступ до налагодження USB для всіх комп’ютерів, які раніше отримали таке право?"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 7e3723c..3aec6aee 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"مربوط (کوئی میڈیا نہیں ہے)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"مربوط (کسی پیغام تک رسائی نہیں ہے)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"مربوط (کوئی فون یا میڈیا نہیں ہے)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"منسلک ہے، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"منسلک ہے (کوئی فون نہیں)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"منسلک ہے (کوئی میڈیا نہیں)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"منسلک ہے (کوئی فون یا میڈیا نہیں)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"میڈيا آڈیو"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"فون کالز"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"فائل کی منتقلی"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"‏Wi‑Fi سے موبائل کو جارحانہ ہینڈ اوور"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏ہمیشہ Wi‑Fi روم اسکینز کی اجازت دیں"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ہارڈویئر کی سرعت کاری میں ربط بنایا جا رہا ہے"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"مطلق والیوم کو غیر فعال کریں"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ان بینڈ رنگنگ فعال کریں"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"‏بلوٹوتھ AVRCP ورژن"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"فرضی مقامات کی اجازت دیں"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"منظر انتساب کے معائنہ کو فعال کریں"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏Wi‑Fi فعال ہونے پر بھی موبائل ڈیٹا کو ہمیشہ فعال رکھیں (تیزی سے نیٹ ورک سوئچ کرنے کیلئے)۔"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"اگر دستیاب ہو، تو ہارڈویئر کی سرعت کاری میں ربط کاری کا استعمال کریں"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏USB ڈیبگ کرنے کی اجازت دیں؟"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏USB ڈیبگ کرنا صرف ڈیولپمنٹ کے مقاصد کیلئے ہے۔ اپنے کمپیوٹر اور اپنے آلہ کے درمیان ڈیٹا کاپی کرنے کیلئے اسے استعمال کریں، بغیر اطلاع کے اپنے آلہ پر ایپس انسٹال کریں اور لاگ ڈیٹا پڑھیں۔"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"‏اپنے ذریعہ پہلے سے اجازت یافتہ سبھی کمپیوٹرز سے USB ڈیبگ کرنے کی رسائی کو کالعدم کریں؟"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 0d9bc50..5c4d3bd 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ulanildi (mediadan tashqari)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Ulangan (xabarlarga kirib bo‘lmaydi)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ulangan (telefon yoki media qurilma emas)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Ulangan, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Ulangan (HSP/HFP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Ulangan (A2DP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Ulangan (HSP/HFP/A2DP dan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefon chaqiruvlari"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl o‘tkazish"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Mobil internetga o‘tish"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi tarmoqlarini qidirishga doim ruxsat"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil internet doim yoniq tursin"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Modem rejimida apparatli tezlashtirish"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Ovoz balangligining mutlaq darajasini o‘chirib qo‘yish"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Bitta liniyada jiringlashni yoqish"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP versiyasi"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Joylashuv emulyatsiyasiga ruxsat berish"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Alomatlar tekshiruvini yoqish"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobil internet har doim yoniq tursin, hatto Wi-Fi yoniq bo‘lsa ham (bir tarmoqdan ikkinchisiga tezroq o‘tish uchun)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Modem rejimida apparatli tezlashtirishdan foydalanish (agar mavjud bo‘lsa)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB orqali nosozliklarni tuzatishga ruxsat berilsinmi?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB orqali nosozliklarni tuzatish faqat dasturlash maqsadlarida yoqiladi. Undan ma‘lumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal ma‘lumotlarini o‘qish uchun foydalaniladi."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"USB orqali nosozliklarni tuzatishga berilgan ruxsat siz hisobingizga kirgan barcha kompyuterlar uchun bekor qilinsinmi?"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 4bf4ec4..db2b29d 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Đã kết nối (không có phương tiện)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Đã kết nối (không truy cập tin nhắn)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Đã k.nối (kg có ĐT hoặc p.tiện nào)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Đã kết nối, mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Đã kết nối (không có điện thoại), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Đã kết nối (không có phương tiện), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Đã kết nối (không có điện thoại hoặc phương tiện), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Âm thanh của phương tiện"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Cuộc gọi điện thoại"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Chuyển tệp"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Chuyển vùng Wi‑Fi tích cực sang mạng DĐ"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luôn cho phép quét chuyển vùng Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dữ liệu di động luôn hiện hoạt"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tăng tốc phần cứng cho chia sẻ kết nối"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Vô hiệu hóa âm lượng tuyệt đối"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Bật đổ chuông trong dải"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth phiên bản AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Cho phép vị trí mô phỏng"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Cho phép kiểm tra thuộc tính của chế độ xem"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Luôn giữ cho dữ liệu di động hoạt động, ngay cả khi Wi-Fi đang hoạt động (để chuyển đổi mạng nhanh)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Sử dụng tăng tốc phần cứng cho chia sẻ kết nối nếu được"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Cho phép gỡ lỗi USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Gỡ lỗi USB chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị của bạn mà không thông báo và đọc dữ liệu nhật ký."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Thu hồi quyền truy cập gỡ lỗi USB từ tất cả máy tính mà bạn đã ủy quyền trước đó?"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index addd04d5..1fe8778 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"已连接(无媒体)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已连接(无消息权限)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已连接(没有手机或媒体信号)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"已连接,电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"已连接(无手机),电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"已连接(无媒体),电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"已连接(无手机或媒体),电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒体音频"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通话"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"文件传输"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"主动从 WLAN 网络切换到移动数据网络"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允许WLAN漫游扫描"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"始终开启移动数据网络"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"网络共享硬件加速"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用绝对音量功能"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"启用手机默认铃声"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"蓝牙 AVRCP 版本"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"允许模拟位置"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"启用视图属性检查功能"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"始终开启移动数据网络,即使 WLAN 网络已开启(便于快速切换网络)。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"使用网络共享硬件加速功能(如果可用)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"是否允许 USB 调试?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 调试仅用于开发目的。该功能可用于在您的计算机和设备之间复制数据、在您的设备上安装应用(事先不发通知)以及读取日志数据。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"是否针对您之前授权的所有计算机撤消 USB 调试的访问权限?"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index ee4ff6b..080a417 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"已連線 (無媒體)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已連結 (無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已連線 (無手機或媒體)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"已連線 (沒有手機),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"已連線 (沒有媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"已連線 (沒有手機或媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音效"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通話"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"檔案傳輸"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"加強 Wi-Fi 至流動數據轉換"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"永遠允許 Wi-Fi 漫遊掃瞄"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"一律保持啟用流動數據"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"網絡共享硬件加速"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"啟用頻內鈴聲"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"允許模擬位置"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"啟用檢視屬性檢查"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"即使 Wi‑Fi 已啟用,仍永遠啟用流動數據 (可快速切換網絡)。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"使用網絡共享硬件加速功能 (如果可用)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"允許 USB 偵錯嗎?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 偵錯是針對應用程式開發而設計的功能,可讓您在電腦與裝置間複製資料、不用通知即可在裝置上安裝應用程式,以及讀取記錄資料。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"要針對先前授權的所有電腦撤銷 USB 偵錯存取權嗎?"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 0a4e483..b3c5212 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"已連線 (無媒體音訊)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已連線 (無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已連線 (無手機或媒體音訊)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"已連線 (無手機),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"已連線 (無媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"已連線 (無手機或媒體音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音訊"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"通話"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"檔案傳輸"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Wi-Fi 至行動數據轉換強化"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允許 Wi-Fi 漫遊掃描"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"行動數據連線一律保持啟用狀態"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"數據連線硬體加速"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"啟用藍牙同步鈴聲功能"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"藍牙 AVRCP 版本"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"允許模擬位置"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"啟用檢視屬性檢查"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"即使 Wi‑Fi 連線已啟用,一律將行動數據連線保持啟用狀態 (以便快速切換網路)。"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"使用數據連線硬體加速功能 (如果可用的話)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"允許 USB 偵錯嗎?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB 偵錯是針對應用程式開發而設計的功能,可讓你複製電腦和裝置中的資料、不需經由通知即可在裝置上安裝應用程式,以及讀取記錄資料。"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"要針對先前授權的所有電腦撤銷 USB 偵錯權限嗎?"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index a142c32..f3c27a1 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -55,14 +55,10 @@
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Ixhunyiwe (ayikho imidiya)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Kuxhunyiwe (akukho ukufinyelela umlayezo)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Ixhunyiwe (ayikho ifoni noma imidiya)"</string>
-    <!-- no translation found for bluetooth_connected_battery_level (7049181126136692368) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_battery_level (5504193961248406027) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (4751724026365870779) -->
-    <skip />
-    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1549265779323455261) -->
-    <skip />
+    <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Kuxhunyiwe, ibhethri elingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Kuxhunyiwe (ayikho ifoni), ibhethri lingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Kuxhunyiwe (ayikho imidiya), ibhethri lingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Kuxhunyiwe (ayikho ifoni noma imidiya), ibhethri lingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Umsindo wemidiya"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Amakholi efoni"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dlulisa ifayela"</string>
@@ -190,6 +186,7 @@
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Ukudluliselwa okunamandla kakhulu kwe-Wi-Fi ukuya kuselula"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vumela njalo ukuskena kokuzula kwe-Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Idatha yeselula ihlala isebenza"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"I-Tethering hardware acceleration"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Khubaza ivolumu ngokuphelele"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Nika amandla ukukhala okuphakathi nomkhiqizo"</string>
     <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Inguqulo ye-Bluetooth ye-AVRCP"</string>
@@ -221,6 +218,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Vumela izindawo mbumbulu"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Nika amandla ukubuka"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hlala ugcine idatha yeselula isebenza, nanoma i-Wi-Fi isebenza (ngokushintshwa kwenethiwekhi okusheshayo)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Sebenzisa i-tethering hardware acceleration uma itholakala"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Vumela ukulungisa iphutha le-USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Ukulungisa iphutha le-USB kuhloselwe izinjongo zokuthuthukisa kuphela. Ingasebenziselwa ukukopisha idatha phakathi kwekhompyutha yakho nedivaysi yakho, faka izinhlelo zokusebenza kwidivaysi yakho ngaphandle kwesaziso, bese ufunda idatha yefayela lokungena."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Buyisa ukufinyelela ekususeni iphutha le-USB kusuka kuwo wonke amakhompyutha owagunyaze ngaphambilini?"</string>
diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml
index a8a1793..6d852df 100644
--- a/packages/SettingsLib/res/values/attrs.xml
+++ b/packages/SettingsLib/res/values/attrs.xml
@@ -48,4 +48,9 @@
 
     <attr name="footerPreferenceStyle" format="reference" />
 
+    <declare-styleable name="PreferenceImageView">
+        <attr name="maxWidth" format="dimension" />
+        <attr name="maxHeight" format="dimension" />
+    </declare-styleable>
+
 </resources>
diff --git a/packages/SettingsLib/res/values/styles_support_preference.xml b/packages/SettingsLib/res/values/styles_support_preference.xml
new file mode 100644
index 0000000..2a5c30f
--- /dev/null
+++ b/packages/SettingsLib/res/values/styles_support_preference.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 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.
+  -->
+
+<!-- Common style for support lib preference to look like Settings app UI -->
+<resources>
+
+    <dimen name="preference_no_icon_padding_start">72dp</dimen>
+
+    <!-- Fragment style -->
+    <style name="PreferenceFragmentStyle.SettingsBase" parent="@*android:style/PreferenceFragment.Material">
+        <item name="allowDividerAfterLastItem">false</item>
+    </style>
+
+    <!-- Preferences -->
+    <style name="Preference.SettingsBase" parent="@*android:style/Preference.Material">
+        <item name="allowDividerAbove">false</item>
+        <item name="allowDividerBelow">true</item>
+        <item name="singleLineTitle">false</item>
+        <item name="iconSpaceReserved">true</item>
+    </style>
+
+    <!-- Preference category -->
+    <style name="Preference.Category.SettingsBase" parent="@style/Preference.Category.Material">
+        <item name="allowDividerAbove">true</item>
+        <item name="allowDividerBelow">true</item>
+        <item name="android:layout">@layout/preference_category_material_settings</item>
+    </style>
+
+    <!-- Preference screen -->
+    <style name="Preference.Screen.SettingsBase" parent="@style/Preference.PreferenceScreen.Material">
+        <item name="allowDividerAbove">false</item>
+        <item name="allowDividerBelow">true</item>
+        <item name="iconSpaceReserved">true</item>
+    </style>
+
+    <!-- Footer Preferences -->
+    <style name="Preference.FooterPreference.SettingsBase" parent="Preference.SettingsBase">
+        <item name="android:layout">@layout/preference_footer</item>
+        <item name="allowDividerAbove">true</item>
+    </style>
+
+    <!-- Dropdown Preferences -->
+    <style name="Preference.DropdownPreference.SettingsBase" parent="Preference.SettingsBase">
+        <item name="android:layout">@layout/preference_dropdown_material_settings</item>
+    </style>
+
+    <!-- Switch Preferences -->
+    <style name="Preference.SwitchPreference.SettingsBase" parent="@style/Preference.SwitchPreference.Material">
+        <item name="allowDividerAbove">false</item>
+        <item name="allowDividerBelow">true</item>
+        <item name="iconSpaceReserved">true</item>
+        <item name="singleLineTitle">false</item>
+    </style>
+
+    <!-- EditText Preferences -->
+    <style name="Preference.EditTextPreference.SettingsBase"
+           parent="@style/Preference.DialogPreference.EditTextPreference.Material">
+        <item name="allowDividerAbove">false</item>
+        <item name="allowDividerBelow">true</item>
+        <item name="iconSpaceReserved">true</item>
+        <item name="singleLineTitle">false</item>
+    </style>
+
+    <style name="PreferenceThemeOverlay.SettingsBase" parent="@style/PreferenceThemeOverlay.v14.Material">
+        <!-- Parent path frameworks/support/v14/preference/res/values/themes.xml -->
+        <item name="android:scrollbars">vertical</item>
+        <item name="preferenceFragmentStyle">@style/PreferenceFragmentStyle.SettingsBase</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Category.SettingsBase</item>
+        <item name="preferenceScreenStyle">@style/Preference.Screen.SettingsBase</item>
+        <item name="preferenceStyle">@style/Preference.SettingsBase</item>
+        <item name="dialogPreferenceStyle">@style/Preference.SettingsBase</item>
+        <item name="editTextPreferenceStyle">@style/Preference.EditTextPreference.SettingsBase</item>
+        <item name="footerPreferenceStyle">@style/Preference.FooterPreference.SettingsBase</item>
+        <item name="switchPreferenceStyle">@style/Preference.SwitchPreference.SettingsBase</item>
+        <item name="dropdownPreferenceStyle">@style/Preference.DropdownPreference.SettingsBase</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 5767823..dee5a93 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -130,7 +130,7 @@
     }
 
     /** Formats a double from 0.0..1.0 as a percentage. */
-    private static String formatPercentage(double percentage) {
+    public static String formatPercentage(double percentage) {
         return NumberFormat.getPercentInstance().format(percentage);
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java b/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java
index e4e0f7f..c4cbc2b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/InterestingConfigChanges.java
@@ -36,7 +36,8 @@
     }
 
     public boolean applyNewConfig(Resources res) {
-        int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
+        int configChanges = mLastConfiguration.updateFrom(
+                Configuration.generateDelta(mLastConfiguration, res.getConfiguration()));
         boolean densityChanged = mLastDensity != res.getDisplayMetrics().densityDpi;
         if (densityChanged || (configChanges & (mFlags)) != 0) {
             mLastDensity = res.getDisplayMetrics().densityDpi;
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
index 512049f..c79b1466d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
@@ -68,10 +68,8 @@
     public void onClick(DialogInterface dialog, int which) {
         UserHandle user = mSelectedTile.userHandle.get(which);
         // Show menu on top level items.
-        mSelectedTile.intent.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true);
         mSelectedTile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
         getActivity().startActivityAsUser(mSelectedTile.intent, user);
-        ((SettingsDrawerActivity) getActivity()).onProfileTileOpen();
     }
 
     public static void updateUserHandlesIfNeeded(Context context, Tile tile) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index a0eadd0..190f5e6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -169,7 +169,10 @@
         finish();
     }
 
-    public void setTileEnabled(ComponentName component, boolean enabled) {
+    /**
+     * @return whether or not the enabled state actually changed.
+     */
+    public boolean setTileEnabled(ComponentName component, boolean enabled) {
         PackageManager pm = getPackageManager();
         int state = pm.getComponentEnabledSetting(component);
         boolean isEnabled = state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
@@ -183,7 +186,9 @@
                             ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                             : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                     PackageManager.DONT_KILL_APP);
+            return true;
         }
+        return false;
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 596eaef..9ccd332 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -16,7 +16,6 @@
 package com.android.settingslib.wifi;
 
 import android.annotation.MainThread;
-import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -144,7 +143,7 @@
 
     @VisibleForTesting
     Scanner mScanner;
-    private boolean mStaleScanResults = false;
+    private boolean mStaleScanResults = true;
 
     public WifiTracker(Context context, WifiListener wifiListener,
             boolean includeSaved, boolean includeScans) {
@@ -767,20 +766,21 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
-            if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
-                mStaleScanResults = false;
-            }
-
             if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
                 updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                         WifiManager.WIFI_STATE_UNKNOWN));
-            } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||
-                    WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) ||
-                    WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
+            } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
+                mWorkHandler
+                        .obtainMessage(
+                            WorkHandler.MSG_UPDATE_ACCESS_POINTS,
+                            WorkHandler.CLEAR_STALE_SCAN_RESULTS,
+                            0)
+                        .sendToTarget();
+            } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action)
+                    || WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
                 mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
             } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
-                NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
-                        WifiManager.EXTRA_NETWORK_INFO);
+                NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                 mConnected.set(info.isConnected());
 
                 mMainHandler.sendEmptyMessage(MainHandler.MSG_CONNECTED_CHANGED);
@@ -872,6 +872,8 @@
         private static final int MSG_RESUME = 2;
         private static final int MSG_UPDATE_WIFI_STATE = 3;
 
+        private static final int CLEAR_STALE_SCAN_RESULTS = 1;
+
         public WorkHandler(Looper looper) {
             super(looper);
         }
@@ -888,6 +890,9 @@
 
             switch (msg.what) {
                 case MSG_UPDATE_ACCESS_POINTS:
+                    if (msg.arg1 == CLEAR_STALE_SCAN_RESULTS) {
+                        mStaleScanResults = false;
+                    }
                     updateAccessPoints();
                     break;
                 case MSG_UPDATE_NETWORK_INFO:
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 071f921..b6d0c45 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -724,7 +724,7 @@
         verify(mockWifiManager, times(2)).getConfiguredNetworks();
         verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
 
-        verify(mockWifiListener).onAccessPointsChanged();
+        verify(mockWifiListener, never()).onAccessPointsChanged(); // mStaleAccessPoints is true
         assertThat(tracker.getAccessPoints().size()).isEqualTo(2);
         assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
     }
@@ -798,6 +798,25 @@
     }
 
     @Test
+    public void startTrackingShouldNotSendAnyCallbacksUntilScanResultsAreProcessed()
+            throws Exception {
+        WifiTracker tracker = createMockedWifiTracker();
+        startTracking(tracker);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+
+        tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+        tracker.mReceiver.onReceive(
+                mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
+        tracker.mReceiver.onReceive(
+                mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
+
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        verify(mockWifiListener, never()).onAccessPointsChanged();
+
+        sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
+    }
+
+    @Test
     public void disablingWifiShouldClearExistingAccessPoints() throws Exception {
         WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
 
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 8fa217d..2fd7e87 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -38,8 +38,7 @@
     android-support-v7-mediarouter \
     android-support-v7-palette \
     android-support-v14-preference \
-    android-support-v17-leanback \
-    colorextraction
+    android-support-v17-leanback
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     SystemUI-tags \
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index bbb461f..edd0d0d 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -271,21 +271,9 @@
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
             <meta-data android:name="com.android.settings.category"
-                    android:value="com.android.settings.category.system" />
+                    android:value="com.android.settings.category.ia.system" />
         </activity>
 
-        <activity-alias android:name=".tuner.TunerSettingLink"
-                        android:targetActivity=".tuner.TunerActivity"
-                        android:enabled="false"
-                        android:process=":tuner">
-            <intent-filter android:priority="1">
-                <action android:name="com.android.settings.action.EXTRA_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <meta-data android:name="com.android.settings.category"
-                       android:value="com.android.settings.category.ia.system" />
-        </activity-alias>
-
         <activity-alias android:name=".DemoMode"
                   android:targetActivity=".tuner.TunerActivity"
                   android:icon="@drawable/tuner"
@@ -411,7 +399,8 @@
         <!-- started from PipUI -->
         <activity
             android:name=".pip.tv.PipMenuActivity"
-            android:exported="true"
+            android:permission="com.android.systemui.permission.SELF"
+            android:exported="false"
             android:theme="@style/PipTheme"
             android:launchMode="singleTop"
             android:taskAffinity=""
@@ -420,24 +409,10 @@
             android:supportsPictureInPicture="true"
             androidprv:alwaysFocusable="true"
             android:excludeFromRecents="true" />
-        <activity
-            android:name=".pip.tv.PipOverlayActivity"
-            android:exported="true"
-            android:theme="@style/PipTheme"
-            android:taskAffinity=""
-            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|locale|layoutDirection"
-            android:resizeableActivity="true"
-            android:supportsPictureInPicture="true"
-            android:excludeFromRecents="true" />
-        <activity
-            android:name=".pip.tv.PipOnboardingActivity"
-            android:exported="true"
-            android:theme="@style/PipTheme"
-            android:launchMode="singleTop"
-            android:excludeFromRecents="true" />
 
         <activity
             android:name=".pip.phone.PipMenuActivity"
+            android:permission="com.android.systemui.permission.SELF"
             android:theme="@style/PipPhoneOverlayControlTheme"
             android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
             android:excludeFromRecents="true"
diff --git a/packages/SystemUI/colorextraction/Android.mk b/packages/SystemUI/colorextraction/Android.mk
deleted file mode 100644
index e818c99..0000000
--- a/packages/SystemUI/colorextraction/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2017 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_ANDROID_LIBRARIES := android-support-annotations \
-     android-support-v7-palette \
-     android-support-v4
-LOCAL_MODULE := colorextraction
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/packages/SystemUI/colorextraction/AndroidManifest.xml b/packages/SystemUI/colorextraction/AndroidManifest.xml
deleted file mode 100644
index 6e082cf..0000000
--- a/packages/SystemUI/colorextraction/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2017 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.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.google.android.colorextraction">
-</manifest>
diff --git a/packages/SystemUI/colorextraction/tests/Android.mk b/packages/SystemUI/colorextraction/tests/Android.mk
deleted file mode 100644
index a517e99..0000000
--- a/packages/SystemUI/colorextraction/tests/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2017 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-    $(call all-java-files-under, ../src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_PACKAGE_NAME := ColorExtractorTests
-LOCAL_CERTIFICATE := platform
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JAVA_LIBRARIES := android-support-test
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-        android-support-test \
-        mockito-target-minus-junit4 \
-        espresso-core \
-        truth-prebuilt \
-        legacy-android-test \
-        android-support-annotations \
-        android-support-v7-palette \
-        android-support-v4
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/packages/SystemUI/colorextraction/tests/AndroidManifest.xml b/packages/SystemUI/colorextraction/tests/AndroidManifest.xml
deleted file mode 100644
index 375c7f2..0000000
--- a/packages/SystemUI/colorextraction/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.systemui.colorextraction.tests">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.systemui.colorextraction.tests"
-        android:label="Tests for ColorExtractor">
-    </instrumentation>
-</manifest>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 0c96b0b..795f20e 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -60,7 +60,7 @@
         <item name="android:layout_gravity">center_horizontal|bottom</item>
     </style>
 
-    <style name="PasswordTheme" parent="@android:style/Theme.DeviceDefault">
+    <style name="PasswordTheme" parent="systemui_theme">
         <item name="android:textColor">?attr/bgProtectTextColor</item>
         <item name="android:colorControlNormal">?attr/bgProtectTextColor</item>
         <item name="android:colorControlActivated">?attr/bgProtectTextColor</item>
diff --git a/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
index 8b5e4b0..8908975 100644
--- a/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24.0dp"
-        android:viewportWidth="40.0"
+        android:viewportWidth="20.0"
         android:viewportHeight="40.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
index 15d521f..5217748 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
+        android:width="12.0dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
index ce37331..c84ac8f 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
index 4a8d0ab..26b68c7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
+        android:width="12.0dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
index e0c6b68..6e4b4c5 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
+        android:width="15.0dp"
+        android:height="20.0dp"
+        android:viewportWidth="18.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
index 5525508..f4b6ed8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
   <group
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
index f499fe7..60a7f1e9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <group android:translateX="3.5" >
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
index 2e6ea23..4ffb4be 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
+        android:width="12dp"
         android:height="24dp"
-        android:viewportWidth="24.0"
+        android:viewportWidth="12.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
       <group
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
index af9c446..816cd32 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
+        android:width="11.9dp"
+        android:height="22dp"
+        android:viewportWidth="13.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
index 5ff7d85..4c43e13 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
+        android:width="15.0dp"
+        android:height="19.5dp"
+        android:viewportWidth="18.5"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
index 3cdd3e1..719a6ca 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
+        android:width="10.5dp"
+        android:height="14.0dp"
+        android:viewportWidth="18.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
index db18fad..62159b3 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
@@ -14,9 +14,9 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
+        android:width="11.08dp"
+        android:height="14.0dp"
+        android:viewportWidth="19.0"
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/layout/global_actions_item.xml b/packages/SystemUI/res/layout/global_actions_item.xml
index 358833c..e3a488c 100644
--- a/packages/SystemUI/res/layout/global_actions_item.xml
+++ b/packages/SystemUI/res/layout/global_actions_item.xml
@@ -18,20 +18,20 @@
      work around this for now with LinearLayouts. -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/global_actions_panel_width"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_gravity="center_vertical"
-    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:layout_gravity="center"
+    android:minWidth="92dp"
+    android:minHeight="92dp"
+    android:gravity="center"
     android:orientation="vertical"
-    android:paddingBottom="24dip"
     android:paddingEnd="8dip"
-    android:paddingStart="8dip"
-    android:paddingTop="24dip">
+    android:paddingStart="8dip">
 
     <ImageView
         android:id="@*android:id/icon"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
         android:layout_gravity="center"
         android:scaleType="center"/>
 
@@ -40,7 +40,9 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="top|center_horizontal"
+        android:paddingTop="10dp"
         android:gravity="center"
+        android:textSize="12sp"
         android:textAppearance="?android:attr/textAppearanceSmall"
         />
 
@@ -50,7 +52,6 @@
         android:layout_height="wrap_content"
         android:layout_gravity="top|center_horizontal"
         android:gravity="center"
-        android:minHeight="26dp"
         android:textColor="?android:attr/textColorTertiary"
         android:textAppearance="?android:attr/textAppearanceSmall"
         />
diff --git a/packages/SystemUI/res/layout/global_actions_wrapped.xml b/packages/SystemUI/res/layout/global_actions_wrapped.xml
index f409c03..528a534 100644
--- a/packages/SystemUI/res/layout/global_actions_wrapped.xml
+++ b/packages/SystemUI/res/layout/global_actions_wrapped.xml
@@ -13,13 +13,9 @@
         android:layout_width="@dimen/global_actions_panel_width"
         android:layout_height="wrap_content"
         android:layout_gravity="top|end"
-        android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
+        android:gravity="center"
         android:orientation="vertical"
-        android:paddingTop="@dimen/volume_dialog_padding_top"
-        android:divider="@null"
-        android:dividerHeight="0dp"
-        android:translationZ="8dp">
-
-    </LinearLayout>
+        android:padding="12dp"
+        android:translationZ="8dp" />
 
 </com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index ef9cf4a..5244122 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -91,6 +91,13 @@
         android:scaleType="center"
         android:tint="?attr/bgProtectTextColor" />
 
-    <include layout="@layout/keyguard_bottom_area_overlay" />
+    <FrameLayout
+        android:id="@+id/overlay_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <include layout="@layout/keyguard_bottom_area_overlay" />
+
+    </FrameLayout>
 
 </com.android.systemui.statusbar.phone.KeyguardBottomAreaView>
diff --git a/packages/SystemUI/res/layout/preference_widget_switch.xml b/packages/SystemUI/res/layout/preference_widget_switch.xml
deleted file mode 100644
index 49610de..0000000
--- a/packages/SystemUI/res/layout/preference_widget_switch.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="wrap_content">
-
-    <RadioButton
-        android:id="@+id/radio_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:clickable="false"
-        android:focusable="false"
-        android:layout_marginEnd="4dp" />
-
-    <View
-        android:layout_width="1dp"
-        android:layout_height="match_parent"
-        android:background="?android:attr/listDivider" />
-
-    <Switch
-        android:id="@*android:id/switch_widget"
-        android:layout_width="50dp"
-        android:layout_height="wrap_content"
-        android:focusable="false"
-        android:clickable="false"
-        android:background="@null" />
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 62ceada..2533b50 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Meer instellings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Klaar"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Gekoppel"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Gekoppel, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Koppel tans …"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"USB-verbinding"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Warmkol"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 17964d8..f524201 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ተጨማሪ ቅንብሮች"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ተከናውኗል"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ተገናኝቷል"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ተገናኝቷል፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"በማገናኘት ላይ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"በማገናኘት ላይ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"መገናኛ ነጥብ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index aabc9d7..adb76b9 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -318,8 +318,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"المزيد من الإعدادات"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"تم"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"متصل"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"الجهاز متّصل، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"جارٍ الاتصال..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"النطاق"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"نقطة اتصال"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a8ad009..a7b3b03 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Digər ayarlar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Hazır"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Qoşulu"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Qoşuldu, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Qoşulur..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Birləşmə"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index ed4eb72..6547f0f 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Još podešavanja"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Povezan"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Povezano, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Povezuje se..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Povezivanje"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 48a56b7..6d6d1b2 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -316,8 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Дадатковыя налады"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Гатова"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Падлучана"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Падключана, узровень зараду акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Падлучэнне..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Мадэм"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Кропка доступу"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index f6fbaf5..86e0278 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Още настройки"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Установена е връзка"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Свързано, батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Установява се връзка..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетъринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка за достъп"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index edcb004..8db54c8 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"আরো সেটিংস"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"সম্পন্ন হয়েছে"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"সংযুক্ত হয়েছে"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"সংযুক্ত হয়েছে, ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"সংযুক্ত হচ্ছে..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"টেদারিং"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"হটস্পট"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b8206a0..451c2f7 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Više postavki"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Povezano"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Povezivanje..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Dijeljenje veze"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Pristupna tačka"</string>
@@ -655,8 +654,8 @@
     <string name="switch_bar_off" msgid="8803270596930432874">"Isključeno"</string>
     <string name="nav_bar" msgid="1993221402773877607">"Navigaciona traka"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"Raspored"</string>
-    <string name="left_nav_bar_button_type" msgid="8555981238887546528">"Dodatni tip dugmeta lijevo"</string>
-    <string name="right_nav_bar_button_type" msgid="2481056627065649656">"Dodatni tip dugmeta desno"</string>
+    <string name="left_nav_bar_button_type" msgid="8555981238887546528">"Vrsta dodatnog dugmeta lijevo"</string>
+    <string name="right_nav_bar_button_type" msgid="2481056627065649656">"Vrsta dodatnog dugmeta desno"</string>
     <string name="nav_bar_default" msgid="8587114043070993007">"(zadano)"</string>
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Međumemorija"</item>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0675706..5aa85b8 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Més opcions"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Fet"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connectat"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connectat (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria)"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"S\'està connectant..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Compartició de xarxa"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Punt d\'accés Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 7a0fbfc..ed4bd0f 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -316,8 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Další nastavení"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Hotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Připojeno"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Připojeno, baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Připojování..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Sdílené připojení"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 08f5761..c7367be 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Flere indstillinger"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Udfør"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tilsluttet"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Tilsluttet – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Opretter forbindelse…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Netdeling"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 50d0a44..0e32df5 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -314,8 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Weitere Einstellungen"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Fertig"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Verbunden"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Verbunden, Akkustand <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Verbindung wird hergestellt…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -731,8 +730,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimieren"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Schließen"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Zum Schließen nach unten ziehen"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Menü \"Bild-in-Bild\""</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ist in Bild-in-Bild"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Menü \"Bild im Bild\""</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ist in Bild im Bild"</string>
     <string name="pip_notification_message" msgid="5619512781514343311">"Wenn du nicht möchtest, dass <xliff:g id="NAME">%s</xliff:g> diese Funktion verwendet, tippe, um die Einstellungen zu öffnen und die Funktion zu deaktivieren."</string>
     <string name="pip_play" msgid="1417176722760265888">"Wiedergeben"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Pausieren"</string>
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
index c83a52e..adae259 100644
--- a/packages/SystemUI/res/values-de/strings_tv.xml
+++ b/packages/SystemUI/res/values-de/strings_tv.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Bild-in-Bild"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Bild im Bild"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Kein Programmtitel)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP schließen"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Vollbild"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 4c4bc00..99cbb93 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Περισσότερες ρυθμίσεις"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Τέλος"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Συνδέθηκε"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Σύνδεση, μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Σύνδεση…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Πρόσδεση"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Σημείο πρόσβασης Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index e832f44..a9cd4dd 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index e832f44..a9cd4dd 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index e832f44..a9cd4dd 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 0fe9d47..94f37b9 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Más configuraciones"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Listo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado. Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Anclaje a red"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 5a0a625..5575dda 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Más opciones"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Listo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Compartir Internet"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f476a35..a08a97a 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Rohkem seadeid"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Valmis"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ühendatud"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ühendatud, aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ühenduse loomine ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Jagamine"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Leviala"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index a36c1c8..0cf5530 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"تنظیمات بیشتر"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"تمام"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"متصل"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"متصل، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"در حال اتصال..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"اتصال به اینترنت با تلفن همراه"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"نقطه اتصال"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 307f5d4..638ca2e 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Lisäasetukset"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Valmis"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Yhdistetty"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Yhdistetty, akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Yhdistetään…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Jaettu yhteys"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5bd0179..25c448a 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Plus de paramètres"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Terminé"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connecté"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connecté. Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connexion en cours…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Partage de connexion"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Point d\'accès sans fil"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 2db32f9..44a26a6 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Plus de paramètres"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"OK"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connecté"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connecté, batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connexion en cours..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Partage de connexion"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Point d\'accès"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index aa83682..68d1c93 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Máis opcións"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Feito"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Dispositivo conectado. Nivel da batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Conexión compartida"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona wifi"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index abc3e46..021ad3e 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"વધુ સેટિંગ્સ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"થઈ ગયું"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"કનેક્ટ થયેલ"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"કનેક્ટ કરેલ, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"કનેક્ટ કરી રહ્યું છે..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ટિથરિંગ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"હોટસ્પોટ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index add9bb6..da3efcf 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"और सेटिंग"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"पूर्ण"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"कनेक्ट है"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"कनेक्ट किया गया, बैटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> है"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"कनेक्ट हो रहा है..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"टेदरिंग"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"हॉटस्पॉट"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 9c610fb..ea7ba5b 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Više  postavki"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Povezano"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Povezivanje..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Dijeljenje veze"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Žarišna točka"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 45ad6be..a47daf5 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"További beállítások"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Kész"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Csatlakoztatva"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Csatlakoztatva; az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Csatlakozás…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Megosztás"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index dbc484f3..0dbee58 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Հավելյալ կարգավորումներ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Պատրաստ է"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Կապակցված է"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Միացված է, մարտկոցի լիցք՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Միանում է..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Մոդեմի ռեժիմ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Թեժ կետ"</string>
@@ -728,7 +727,7 @@
     <string name="pip_phone_close" msgid="8416647892889710330">"Փակել"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Քաշեք վար՝ փակելու համար"</string>
     <string name="pip_menu_title" msgid="3328510504196964712">"«Նկար նկարի մեջ» ռեժիմի ընտրացանկ"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g>-ը «նկարը նկարի մեջ» ռեժիմում է"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g>-ը «Նկար նկարի մեջ» ռեժիմում է"</string>
     <string name="pip_notification_message" msgid="5619512781514343311">"Եթե չեք ցանկանում, որ <xliff:g id="NAME">%s</xliff:g>-ն օգտագործի այս գործառույթը, հպեք՝ կարգավորումները բացելու և այն անջատելու համար։"</string>
     <string name="pip_play" msgid="1417176722760265888">"Նվագարկել"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Դադարեցնել"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 1163900..51d356e2 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Setelan lainnya"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Selesai"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tersambung"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Terhubung, daya baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Menyambung..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Menambatkan"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 8c1c61d..9100ca8 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Fleiri stillingar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Lokið"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tengt"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Tengt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlaða"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Tengist..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tjóðrun"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Heitur reitur"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index df3c443..134503b 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Altre impostazioni"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Fine"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Connesso"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connesso, batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connessione..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index d4cf5d3..22a1464 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -314,8 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"הגדרות נוספות"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"בוצע"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"מחובר"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"מחובר, הסוללה ב-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"מתחבר..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"שיתוף אינטרנט בין ניידים"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"נקודה לשיתוף אינטרנט"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 3eb9060..8b86acc 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"詳細設定"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完了"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"接続済み"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"接続済み、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"接続しています..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"テザリング"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"アクセスポイント"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index c7b977a..72c4215 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"დამატებითი პარამეტრები"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"დასრულდა"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"დაკავშირებულია"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"დაკავშირებულია. ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"დაკავშირება..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"მოდემის რეჟიმი"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"წვდომის წერტილი"</string>
@@ -727,8 +726,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"ჩაკეცვა"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"დახურვა"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"დასახურად ჩავლებით ჩამოიტანეთ ქვემოთ"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"მენიუ „გამოსახულება გამოსახულებაში“"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> იყენებს რეჟიმს „გამოსახულება გამოსახულებაში“"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"მენიუ „ეკრანი ეკრანში“"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> იყენებს რეჟიმს „ეკრანი ეკრანში“"</string>
     <string name="pip_notification_message" msgid="5619512781514343311">"თუ არ გსურთ, რომ <xliff:g id="NAME">%s</xliff:g> ამ ფუნქციას იყენებდეს, აქ შეხებით შეგიძლიათ გახსნათ პარამეტრები და გამორთოთ ის."</string>
     <string name="pip_play" msgid="1417176722760265888">"დაკვრა"</string>
     <string name="pip_pause" msgid="8881063404466476571">"დაპაუზება"</string>
diff --git a/packages/SystemUI/res/values-ka/strings_tv.xml b/packages/SystemUI/res/values-ka/strings_tv.xml
index 1a97590..f4f818b 100644
--- a/packages/SystemUI/res/values-ka/strings_tv.xml
+++ b/packages/SystemUI/res/values-ka/strings_tv.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_channel_tv_pip" msgid="134047986446577723">"სურათი სურათში"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ეკრანი ეკრანში"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(პროგრამის სათაურის გარეშე)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP-ის დახურვა"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"სრულ ეკრანზე"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index dded6d3..5d5f807 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Қосымша параметрлер"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Дайын"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Қосылды"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Қосылды, батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Қосылуда…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетеринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хот-спот"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index b01edb2..e161f59 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ការ​កំណត់​ច្រើន​ទៀត"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"រួចរាល់"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"បាន​ភ្ជាប់"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"បានភ្ជាប់ ហើយថ្មមានកម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"កំពុង​តភ្ជាប់..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ការ​ភ្ជាប់"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ហតស្ប៉ត"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index cad05a6..2284c9b 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ಮುಗಿದಿದೆ"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ಸಂಪರ್ಕಗೊಂಡಿದೆ, ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ಟೆಥರಿಂಗ್‌"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ಹಾಟ್‌ಸ್ಪಾಟ್"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1df6377..6943f4e 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"설정 더보기"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"완료"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"연결됨"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"연결됨, 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"연결 중..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"테더링"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"핫스팟"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index ce3edb5..f3d5dbd 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Дагы жөндөөлөр"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Бүттү"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Туташкан"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Туташып турат, батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Туташууда…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетеринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Туташуу чекити"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 5a889d8..a5f0ca4 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"​ການ​ຕັ້ງ​ຄ່າ​ເພີ່ມ​ເຕີມ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ແລ້ວໆ"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ເຊື່ອມ​ຕໍ່ແລ້ວ"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ເຊື່ອມຕໍ່ແລ້ວ, ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ກຳລັງເຊື່ອມຕໍ່..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"​ການ​ປ່ອນ​ສັນ​ຍານ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"​ຮັອດ​ສະ​ປອດ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index e6df867..c1ccc75 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -314,8 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Daugiau nustatymų"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Atlikta"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Prijungtas"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Prijungta, akumuliatorius <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Prisijungiama..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Susiejimas"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Viešosios interneto prieigos taškas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index d45096d..4d4aad11 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Vairāk iestatījumu"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gatavs"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Pievienota"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Savienojums izveidots, akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Notiek savienojuma izveide…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Piesaiste"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tīklājs"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 9aa8fc4..fb7c7af 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Повеќе поставки"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Поврзано"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Поврзан, ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Се поврзува..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Поврзување"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка на пристап"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 3976176..b42319a 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"കൂടുതൽ ക്രമീകരണങ്ങൾ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"പൂർത്തിയാക്കി"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"കണക്‌റ്റുചെയ്‌തു"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"കണക്‌റ്റുചെയ്‌തു, ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"കണക്റ്റുചെയ്യുന്നു..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ടെതറിംഗ്"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ഹോട്ട്‌സ്‌പോട്ട്"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index f00e8eb..cd4f5be 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -308,8 +308,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Өөр тохиргоо"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Дууссан"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Холбогдсон"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Холбогдож байна..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Модем болгох"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Сүлжээний цэг"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 2ff5e63..b8562f6 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"अधिक सेटिंग्ज"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"पूर्ण झाले"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"कनेक्ट केलेले"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"कनेक्ट केलेले आहे, बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"कनेक्ट करीत आहे..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"टेदरिंग"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"हॉटस्पॉट"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 1c6e543..2c2e094 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Lagi tetapan"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Selesai"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Disambungkan"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Disambungkan, bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Menyambung..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Penambatan"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tempat liputan"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index cf9baee..5040bfd 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"နောက်ထပ် ဆက်တင်များ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"လုပ်ပြီး"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ချိတ်ဆက်ထား"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ချိတ်ဆက်ပြီးပါပြီ၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ဆက်သွယ်နေ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"တွဲချီပေးခြင်း"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ဟော့စပေါ့"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index e14646e..324c583 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Flere innstillinger"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Ferdig"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Tilkoblet"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Tilkoblet, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Kobler til …"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internettdeling"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Wi-Fi-sone"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index a174672..d2a5020 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"थप सेटिङहरू"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"भयो"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"जोडिएको"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"यन्त्र जडान भयो, ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"जडान हुँदै..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"टेदर गर्दै"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"हटस्पट"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index fb494c0..d6a949d 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -32,7 +32,7 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen meldingen"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actief"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meldingen"</string>
-    <string name="battery_low_title" msgid="6456385927409742437">"Accu is bijna leeg"</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Batterij is bijna leeg"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> resterend"</string>
     <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> resterend. Batterijbesparing is ingeschakeld."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Opladen via USB niet ondersteund.\nGebruik alleen de bijgeleverde oplader."</string>
@@ -102,11 +102,11 @@
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kleiner scherm uitzoomen naar groter scherm."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-verbinding ingesteld."</string>
     <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth-verbinding verbroken."</string>
-    <string name="accessibility_no_battery" msgid="358343022352820946">"Geen accu."</string>
-    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Accu: één streepje."</string>
-    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Accu: twee streepjes."</string>
-    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Accu: drie streepjes."</string>
-    <string name="accessibility_battery_full" msgid="8909122401720158582">"Accu is vol."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Geen batterij."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Batterij: één streepje."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Batterij: twee streepjes."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Batterij: drie streepjes."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Batterij is vol."</string>
     <string name="accessibility_no_phone" msgid="4894708937052611281">"Geen telefoonsignaal."</string>
     <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefoon: één streepje."</string>
     <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefoon: twee streepjes."</string>
@@ -161,8 +161,8 @@
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Geen simkaart."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Netwerk van provider wordt gewijzigd."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Accudetails openen"</string>
-    <string name="accessibility_battery_level" msgid="7451474187113371965">"Accu: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
-    <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Accu wordt opgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterij: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batterij wordt opgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeeminstellingen."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meldingen."</string>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Alle meldingen bekijken"</string>
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Meer instellingen"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gereed"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Verbonden"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Verbonden, batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Verbinding maken…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
@@ -506,7 +505,7 @@
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Volumeknoppen van %s worden weergegeven. Veeg omhoog om te sluiten."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volumeknoppen verborgen"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Systeem-UI-tuner"</string>
-    <string name="show_battery_percentage" msgid="5444136600512968798">"Percentage ingebouwde accu weergeven"</string>
+    <string name="show_battery_percentage" msgid="5444136600512968798">"Percentage ingebouwde batterij weergeven"</string>
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Accupercentage weergeven in het pictogram op de statusbalk wanneer er niet wordt opgeladen"</string>
     <string name="quick_settings" msgid="10042998191725428">"Snelle instellingen"</string>
     <string name="status_bar" msgid="4877645476959324760">"Statusbalk"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 23f60fd..c321759 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"ਹੋਰ ਸੈਟਿੰਗਾਂ"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ਹੋ ਗਿਆ"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ, ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ਟੀਥਰਿੰਗ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ਹੌਟਸਪੌਟ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 5c7b037..279d121 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -314,8 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Więcej ustawień"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Gotowe"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Połączono"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Połączono, bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Łączę..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Powiązanie"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index e0e1c76..d28d7d3 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mais configurações"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Concluído"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Ponto de acesso"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 37e1c7ed..27f859b 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mais definições"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Concluído"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ligado"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ligado, bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"A ligar..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Associação"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index e0e1c76..d28d7d3 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mais configurações"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Concluído"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectado, nível da bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Ponto de acesso"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index be529f3..0224ef5 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -314,8 +314,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mai multe setări"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Terminat"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectat"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Conectat, bateria la <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Se conectează..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 88deda0..f8dc744 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -316,8 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Настройки"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Подключено"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Подключено, уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Соединение..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Режим модема"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка доступа"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 9cd3701..7e77c43 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"තව සැකසීම්"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"නිමයි"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"සම්බන්ධිත"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"සම්බන්ධිතයි, බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"සම්බන්ධ වෙමින්..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ටෙදරින්"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"හොට්ස්පොට්"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index a93013e..2b19d6f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -316,8 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Ďalšie nastavenia"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Hotovo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Pripojené"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Pripojené, stav batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Pripája sa..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Zdieľané pripojenie"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 449ac24..29dfa3a 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -316,8 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Več nastavitev"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Končano"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Povezava je vzpostavljena"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Povezava je vzpostavljena, raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Vzpostavljanje povezave ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internet prek mobilne naprave"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Dostopna točka"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a254953..0423208 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Cilësime të tjera"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"U krye!"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"I lidhur"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"E lidhur, bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Po lidhet..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Lidhje çiftimi"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Qasje në zona publike interneti"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 561a56a..d6adcb5 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Још подешавања"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Повезан"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Повезује се..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Повезивање"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хотспот"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index cb5c214..642484f 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Fler inställningar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Klart"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ansluten"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ansluten, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ansluter ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internetdelning"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Trådlös surfzon"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 31d2328..e11313e 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Mipangilio zaidi"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Nimemaliza"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Imeunganishwa"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Imeunganishwa, kiwango cha betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Inaunganisha..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Kusambaza mtandao"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Mtandao-hewa"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 30defe3..e0a0e9b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"அமைப்பில் மாற்று"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"முடிந்தது"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"இணைக்கப்பட்டது"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"இணைக்கப்பட்டது, பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"இணைக்கிறது..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"டெதெரிங்"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ஹாட்ஸ்பாட்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 2a2d394..1787d07 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"మరిన్ని సెట్టింగ్‌లు"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"పూర్తయింది"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"కనెక్ట్ చేయబడినది"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"కనెక్ట్ చేయబడింది, బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"కనెక్ట్ అవుతోంది..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"టీథరింగ్"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"హాట్‌స్పాట్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 969ba34..a0db287 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"การตั้งค่าเพิ่มเติม"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"เสร็จสิ้น"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"เชื่อมต่อ"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"เชื่อมต่ออยู่ แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"กำลังเชื่อมต่อ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"การปล่อยสัญญาณ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ฮอตสปอต"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 1d223d03..5b6732c 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Marami pang setting"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Tapos na"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Nakakonekta"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Nakakonekta, baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Kumokonekta..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Nagte-tether"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 0b2fa4e..ad6c498 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Diğer ayarlar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Bitti"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Bağlı"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Bağlandı, pil seviyesi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Bağlanılıyor..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index d11cfda..d79200a 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -316,8 +316,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Більше налаштувань"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Готово"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Під’єднано"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Під’єдано, заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"З’єднання…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Режим модема"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка доступу"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index e071922..c59242f 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"مزید ترتیبات"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"ہو گیا"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"مربوط"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"منسلک ہے، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"مربوط ہو رہا ہے…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ٹیتھرنگ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ہاٹ اسپاٹ"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index cf6fa00..4946f69 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Boshqa sozlamalar"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Tayyor"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ulangan"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Ulangan, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ulanmoqda…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Modem rejimi"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 5b884ec..e716899 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Cài đặt khác"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Xong"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Đã kết nối"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Đã kết nối, mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Đang kết nối..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Đang dùng làm điểm truy cập Internet"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Điểm phát sóng"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 5fc1ff6..e29ccb6 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -312,8 +312,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"更多設定"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完成"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"已連線"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"正在連線…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"網絡共享"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"熱點"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9bbb188..2656550 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"更多設定"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完成"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"已連線"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"連線中..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"網路共用"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"無線基地台"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 1a70bc4..e66ff73 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -310,8 +310,7 @@
     <string name="quick_settings_more_settings" msgid="326112621462813682">"Izilungiselelo eziningi"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"Kwenziwe"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Ixhunyiwe"</string>
-    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
-    <skip />
+    <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Kuxhunyiwe, ibhethri elingu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Iyaxhuma..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Ukusebenzisa njengemodemu"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"I-Hotspot"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1fd9b2e..b02f189 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -819,9 +819,9 @@
 
     <dimen name="hwui_edge_margin">16dp</dimen>
 
-    <dimen name="global_actions_panel_width">125dp</dimen>
+    <dimen name="global_actions_panel_width">120dp</dimen>
 
-    <dimen name="global_actions_top_padding">100dp</dimen>
+    <dimen name="global_actions_top_padding">120dp</dimen>
 
     <!-- the maximum offset in either direction that elements are moved horizontally to prevent
             burn-in on AOD -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 93a0742..e9dd7e6 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -314,6 +314,7 @@
     <style name="LockPatternStyle">
         <item name="*android:regularColor">?android:attr/textColorPrimaryInverse</item>
         <item name="*android:successColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="*android:errorColor">?android:attr/colorError</item>
     </style>
 
     <!-- Overlay manager may replace this theme -->
@@ -434,8 +435,7 @@
         <item name="preferenceTheme">@style/TunerPreferenceTheme</item>
     </style>
 
-    <style name="TunerPreferenceTheme" parent="@android:style/Theme.DeviceDefault.Settings">
-        <item name="dropdownPreferenceStyle">@style/Preference.DropDown.Material</item>
+    <style name="TunerPreferenceTheme" parent="@style/PreferenceThemeOverlay.SettingsBase">
     </style>
 
     <style name="TextAppearance.NotificationInfo">
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index bb44123..776d076 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -268,6 +268,9 @@
         mProviders.put(AccessibilityManagerWrapper.class,
                 () -> new AccessibilityManagerWrapper(mContext));
 
+        // Creating a new instance will trigger color extraction.
+        // Thankfully this only happens once - during boot - and WallpaperManagerService
+        // loads colors from cache.
         mProviders.put(SysuiColorExtractor.class, () -> new SysuiColorExtractor(mContext));
 
         mProviders.put(TunablePaddingService.class, () -> new TunablePaddingService());
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 7fed3e8..377fab5 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -545,6 +545,16 @@
      */
     @VisibleForTesting
     void finishExpanding(boolean forceAbort, float velocity) {
+        finishExpanding(forceAbort, velocity, true /* allowAnimation */);
+    }
+
+    /**
+     * Finish the current expand motion
+     * @param forceAbort whether the expansion should be forcefully aborted and returned to the old
+     *                   state
+     * @param velocity the velocity this was expanded/ collapsed with
+     */
+    private void finishExpanding(boolean forceAbort, float velocity, boolean allowAnimation) {
         if (!mExpanding) return;
 
         if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView);
@@ -568,7 +578,7 @@
         mCallback.expansionStateChanged(false);
         int naturalHeight = mScaler.getNaturalHeight();
         float targetHeight = nowExpanded ? naturalHeight : mSmallSize;
-        if (targetHeight != currentHeight && mEnabled) {
+        if (targetHeight != currentHeight && mEnabled && allowAnimation) {
             mScaleAnimation.setFloatValues(targetHeight);
             mScaleAnimation.setupStartValues();
             final View scaledView = mResizedView;
@@ -622,10 +632,22 @@
     }
 
     /**
+     * Use this to abort any pending expansions in progress and force that there will be no
+     * animations.
+     */
+    public void cancelImmediately() {
+        cancel(false /* allowAnimation */);
+    }
+
+    /**
      * Use this to abort any pending expansions in progress.
      */
     public void cancel() {
-        finishExpanding(true /* forceAbort */, 0f /* velocity */);
+        cancel(true /* allowAnimation */);
+    }
+
+    private void cancel(boolean allowAnimation) {
+        finishExpanding(true /* forceAbort */, 0f /* velocity */, allowAnimation);
         clearView();
 
         // reset the gesture detector
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
index 22bb2a3..ca34345 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -193,8 +193,8 @@
     private void swapOrder(LinearLayout linearLayout) {
         ArrayList<View> children = new ArrayList<>();
         for (int i = 0; i < linearLayout.getChildCount(); i++) {
-            children.add(0, linearLayout.getChildAt(i));
-            linearLayout.removeViewAt(i);
+            children.add(0, linearLayout.getChildAt(0));
+            linearLayout.removeViewAt(0);
         }
         children.forEach(v -> linearLayout.addView(v));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 5f393d0..ccb8117 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -27,10 +27,9 @@
 import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.VisibleForTesting;
-
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.types.ExtractionType;
-import com.google.android.colorextraction.types.Tonal;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
 
 /**
  * ColorExtractor aware of wallpaper visibility
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java
new file mode 100644
index 0000000..0aeb128
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 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.doze;
+
+/**
+ * Forwards the currently used brightness to {@link DozeHost}.
+ */
+public class DozeBrightnessHostForwarder extends DozeMachine.Service.Delegate {
+
+    private final DozeHost mHost;
+
+    public DozeBrightnessHostForwarder(DozeMachine.Service wrappedService, DozeHost host) {
+        super(wrappedService);
+        mHost = host;
+    }
+
+    @Override
+    public void setDozeScreenBrightness(int brightness) {
+        super.setDozeScreenBrightness(brightness);
+        mHost.setDozeScreenBrightness(brightness);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 4804ac2..91ca571 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -49,8 +49,12 @@
         WakeLock wakeLock = new DelayedWakeLock(handler,
                 WakeLock.createPartial(context, "Doze"));
 
-        DozeMachine.Service wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(
-                DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params), params);
+        DozeMachine.Service wrappedService = dozeService;
+        wrappedService = new DozeBrightnessHostForwarder(wrappedService, host);
+        wrappedService = DozeScreenStatePreventingAdapter.wrapIfNeeded(wrappedService, params);
+        wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(wrappedService,
+                params);
+
         DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock);
         machine.setParts(new DozeMachine.Part[]{
                 new DozePauser(handler, machine, alarmManager),
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 5aaa6c7..57fb14e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -31,6 +31,8 @@
     void dozeTimeTick();
     boolean isPowerSaveActive();
     boolean isPulsingBlocked();
+    boolean isProvisioned();
+    boolean isBlockingDoze();
 
     void startPendingIntentDismissingKeyguard(PendingIntent intent);
     void abortPulsing();
@@ -40,6 +42,8 @@
 
     void onDoubleTap(float x, float y);
 
+    void setDozeScreenBrightness(int value);
+
     interface Callback {
         default void onNotificationHeadsUp() {}
         default void onPowerSaveChanged(boolean active) {}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index af02e5b..ce0a151 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -248,6 +248,12 @@
         }
     }
 
+    public static void traceSensor(Context context, int pulseReason) {
+        if (!ENABLED) return;
+        init(context);
+        log("sensor type=" + pulseReasonToString(pulseReason));
+    }
+
     private static class SummaryStats {
         private int mCount;
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 67de020..545a1ea 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -174,6 +174,7 @@
         for (TriggerSensor s : mSensors) {
             pw.print("Sensor: "); pw.println(s.toString());
         }
+        pw.print("ProxSensor: "); pw.println(mProxSensor.toString());
     }
 
     private class ProxSensor implements SensorEventListener {
@@ -232,7 +233,9 @@
             mProxCallback.accept(mCurrentlyFar);
 
             long now = SystemClock.elapsedRealtime();
-            if (!mCurrentlyFar) {
+            if (mCurrentlyFar == null) {
+                // Sensor has been unregistered by the proxCallback. Do nothing.
+            } else if (!mCurrentlyFar) {
                 mLastNear = now;
             } else if (mCurrentlyFar && now - mLastNear < COOLDOWN_TRIGGER) {
                 // If the last near was very recent, we might be using more power for prox
@@ -246,6 +249,12 @@
         @Override
         public void onAccuracyChanged(Sensor sensor, int accuracy) {
         }
+
+        @Override
+        public String toString() {
+            return String.format("{registered=%s, requested=%s, coolingDown=%s, currentlyFar=%s}",
+                    mRegistered, mRequested, mCooldownTimer.isScheduled(), mCurrentlyFar);
+        }
     }
 
     private class TriggerSensor extends TriggerEventListener {
@@ -312,6 +321,7 @@
         @Override
         @AnyThread
         public void onTrigger(TriggerEvent event) {
+            DozeLog.traceSensor(mContext, mPulseReason);
             mHandler.post(mWakeLock.wrap(() -> {
                 if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
                 boolean sensorPerformsProxCheck = false;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 9981972..ec6caf1 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -172,14 +172,6 @@
         }
     }
 
-    private void onCarMode() {
-        mMachine.requestState(DozeMachine.State.FINISH);
-    }
-
-    private void onPowerSave() {
-        mMachine.requestState(DozeMachine.State.FINISH);
-    }
-
     @Override
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
@@ -215,11 +207,11 @@
     }
 
     private void checkTriggersAtInit() {
-        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
-            onCarMode();
-        }
-        if (mDozeHost.isPowerSaveActive()) {
-            onPowerSave();
+        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
+                || mDozeHost.isPowerSaveActive()
+                || mDozeHost.isBlockingDoze()
+                || !mDozeHost.isProvisioned()) {
+            mMachine.requestState(DozeMachine.State.FINISH);
         }
     }
 
@@ -355,7 +347,7 @@
                 requestPulse(DozeLog.PULSE_REASON_INTENT, false /* performedProxCheck */);
             }
             if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
-                onCarMode();
+                mMachine.requestState(DozeMachine.State.FINISH);
             }
             if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
                 mDozeSensors.onUserSwitched();
@@ -391,7 +383,7 @@
         @Override
         public void onPowerSaveChanged(boolean active) {
             if (active) {
-                onPowerSave();
+                mMachine.requestState(DozeMachine.State.FINISH);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 31d41ac..9b113d8 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -14,9 +14,9 @@
 
 package com.android.systemui.globalactions;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
 import com.android.internal.R;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.EmergencyAffordanceManager;
@@ -28,10 +28,11 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
 import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.volume.VolumeDialogImpl;
 import com.android.systemui.volume.VolumeDialogMotion.LogAccelerateInterpolator;
 import com.android.systemui.volume.VolumeDialogMotion.LogDecelerateInterpolator;
 
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.ActivityManager;
 import android.app.Dialog;
 import android.app.WallpaperManager;
@@ -42,11 +43,7 @@
 import android.content.IntentFilter;
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
-import android.database.DataSetObserver;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
 import android.graphics.Point;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
@@ -68,11 +65,9 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
-import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewPropertyAnimator;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
@@ -85,9 +80,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.ColorExtractor.GradientColors;
-import com.google.android.colorextraction.drawable.GradientDrawable;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -1304,6 +1297,7 @@
                                 * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
                         mGradientDrawable.setAlpha(alpha);
                     })
+                    .withEndAction(() -> getWindow().getDecorView().requestAccessibilityFocus())
                     .start();
         }
 
@@ -1333,6 +1327,13 @@
                     .translationX(getAnimTranslation())
                     .setDuration(300)
                     .setInterpolator(new LogAccelerateInterpolator())
+                    .setUpdateListener(animation -> {
+                        float frac = animation.getAnimatedFraction();
+                        float alpha = frac *(ScrimController.GRADIENT_SCRIM_ALPHA_BUSY
+                                        - ScrimController.GRADIENT_SCRIM_ALPHA)
+                                + ScrimController.GRADIENT_SCRIM_ALPHA;
+                        mGradientDrawable.setAlpha((int) (alpha * 255));
+                    })
                     .start();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index a5ee198..13ba7c1 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -388,6 +388,11 @@
 
     private void updateFromIntent(Intent intent) {
         mToControllerMessenger = intent.getParcelableExtra(EXTRA_CONTROLLER_MESSENGER);
+        if (mToControllerMessenger == null) {
+            Log.w(TAG, "Controller messenger is null. Stopping.");
+            finish();
+            return;
+        }
         notifyActivityCallback(mMessenger);
 
         // Register for HidePipMenuEvents once we notify the controller of this activity
@@ -567,6 +572,9 @@
     }
 
     private void sendMessage(Message m, String errorMsg) {
+        if (mToControllerMessenger == null) {
+            return;
+        }
         try {
             mToControllerMessenger.send(m);
         } catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 9588b03..278fdc3 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -30,6 +30,7 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
@@ -401,7 +402,7 @@
     /**
      * Updates the appearance of the menu and scrim on top of the PiP while dismissing.
      */
-    void updateDismissFraction() {
+    private void updateDismissFraction() {
         if (mMenuController != null) {
             Rect bounds = mMotionHelper.getBounds();
             final float target = mMovementBounds.bottom + bounds.height();
@@ -427,7 +428,7 @@
     /**
      * Sets the minimized state.
      */
-    void setMinimizedStateInternal(boolean isMinimized) {
+    private void setMinimizedStateInternal(boolean isMinimized) {
         if (!ENABLE_MINIMIZE) {
             return;
         }
@@ -466,7 +467,7 @@
     /**
      * Sets the menu visibility.
      */
-    void setMenuState(int menuState, boolean resize) {
+    private void setMenuState(int menuState, boolean resize) {
         if (menuState == MENU_STATE_FULL) {
             // Save the current snap fraction and if we do not drag or move the PiP, then
             // we store back to this snap fraction.  Otherwise, we'll reset the snap
@@ -534,7 +535,8 @@
     private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() {
         // Whether the PiP was on the left side of the screen at the start of the gesture
         private boolean mStartedOnLeft;
-        private Point mStartPosition;
+        private final Point mStartPosition = new Point();
+        private final PointF mDelta = new PointF();
 
         @Override
         public void onDown(PipTouchState touchState) {
@@ -543,7 +545,8 @@
             }
 
             Rect bounds = mMotionHelper.getBounds();
-            mStartPosition = new Point(bounds.left, bounds.top);
+            mDelta.set(0f, 0f);
+            mStartPosition.set(bounds.left, bounds.top);
             mStartedOnLeft = bounds.left < mMovementBounds.centerX();
             mMovementWithinMinimize = true;
             mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
@@ -577,10 +580,11 @@
 
             if (touchState.isDragging()) {
                 // Move the pinned stack freely
-                mTmpBounds.set(mMotionHelper.getBounds());
                 final PointF lastDelta = touchState.getLastTouchDelta();
-                float left = mTmpBounds.left + lastDelta.x;
-                float top = mTmpBounds.top + lastDelta.y;
+                float lastX = mStartPosition.x + mDelta.x;
+                float lastY = mStartPosition.y + mDelta.y;
+                float left = lastX + lastDelta.x;
+                float top = lastY + lastDelta.y;
                 if (!touchState.allowDraggingOffscreen() || !ENABLE_MINIMIZE) {
                     left = Math.max(mMovementBounds.left, Math.min(mMovementBounds.right, left));
                 }
@@ -590,6 +594,12 @@
                 } else {
                     top = Math.max(mMovementBounds.top, Math.min(mMovementBounds.bottom, top));
                 }
+
+                // Add to the cumulative delta after bounding the position
+                mDelta.x += left - lastX;
+                mDelta.y += top - lastY;
+
+                mTmpBounds.set(mMotionHelper.getBounds());
                 mTmpBounds.offsetTo((int) left, (int) top);
                 mMotionHelper.movePip(mTmpBounds);
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
index b2b5b02..dd3361b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -61,7 +61,7 @@
     }
 
     /**
-     * Processess a given touch event and updates the state.
+     * Processes a given touch event and updates the state.
      */
     public void onTouchEvent(MotionEvent ev) {
         switch (ev.getAction()) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
index 82018ce..e437eff 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
@@ -45,6 +45,9 @@
     @Override
     protected void onCreate(Bundle bundle) {
         super.onCreate(bundle);
+        if (!mPipManager.isPipShown()) {
+            finish();
+        }
         setContentView(R.layout.tv_pip_menu);
         mPipManager.addListener(this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index 94da5f7..9eb29f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -160,8 +160,9 @@
                 .addFloat(mSettingsButton, "rotation", -120, 0)
                 .build();
         if (mAlarmShowing) {
+            int translate = isLayoutRtl() ? mDate.getWidth() : -mDate.getWidth();            
             mAlarmAnimator = new Builder().addFloat(mDate, "alpha", 1, 0)
-                    .addFloat(mDateTimeGroup, "translationX", 0, -mDate.getWidth())
+                    .addFloat(mDateTimeGroup, "translationX", 0, translate)
                     .addFloat(mAlarmStatus, "alpha", 0, 1)
                     .setListener(new ListenerAdapter() {
                         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index cdd0ebc..5ab3927 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -96,6 +96,7 @@
             int padding = state.icon != null ? state.icon.getPadding() : 0;
             if (d != null) {
                 d.setAutoMirrored(false);
+                d.setLayoutDirection(getLayoutDirection());
             }
             iv.setImageDrawable(d);
             if (state.slash != null && iv instanceof SlashImageView) {
@@ -144,22 +145,26 @@
     }
 
     public static void animateGrayScale(int fromColor, int toColor, ImageView iv) {
-        final float fromAlpha = Color.alpha(fromColor);
-        final float toAlpha = Color.alpha(toColor);
-        final float fromChannel = Color.red(fromColor);
-        final float toChannel = Color.red(toColor);
+        if (ValueAnimator.areAnimatorsEnabled()) {
+            final float fromAlpha = Color.alpha(fromColor);
+            final float toAlpha = Color.alpha(toColor);
+            final float fromChannel = Color.red(fromColor);
+            final float toChannel = Color.red(toColor);
 
-        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-        anim.setDuration(QS_ANIM_LENGTH);
+            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+            anim.setDuration(QS_ANIM_LENGTH);
+            anim.addUpdateListener(animation -> {
+                float fraction = animation.getAnimatedFraction();
+                int alpha = (int) (fromAlpha + (toAlpha - fromAlpha) * fraction);
+                int channel = (int) (fromChannel + (toChannel - fromChannel) * fraction);
 
-        anim.addUpdateListener(animation -> {
-            float fraction = animation.getAnimatedFraction();
-            int alpha = (int) (fromAlpha + (toAlpha - fromAlpha) * fraction);
-            int channel = (int) (fromChannel + (toChannel - fromChannel) * fraction);
+                setTint(iv, Color.argb(alpha, channel, channel, channel));
+            });
 
-            setTint(iv, Color.argb(alpha, channel, channel, channel));
-        });
-        anim.start();
+            anim.start();
+        } else {
+            setTint(iv, toColor);
+        }
     }
 
     public static void setTint(ImageView iv, int color) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 089d07a..3f419a8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -80,7 +80,7 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.state = mCharging ? Tile.STATE_UNAVAILABLE
+        state.state = mPluggedIn ? Tile.STATE_UNAVAILABLE
                 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         BatterySaverIcon bsi = new BatterySaverIcon();
         bsi.mState = state.state;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index c1c41be0..fd37b17 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -42,6 +42,7 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
@@ -82,8 +83,7 @@
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.phone.ScrimController;
 
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.drawable.GradientDrawable;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index ae665c7..e5aad033 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -32,6 +32,7 @@
     private final boolean mHasOverlappingRendering;
     AnimationDrawable mAnim;
     boolean mAttached;
+    private boolean mAllowAnimation;
 
     // Tracks the last image that was set, so that we don't refresh the image if it is exactly
     // the same as the previous one. If this is a resid, we track that. If it's a drawable, we
@@ -56,6 +57,17 @@
         }
     }
 
+    public void setAllowAnimation(boolean allowAnimation) {
+        if (mAllowAnimation != allowAnimation) {
+            mAllowAnimation = allowAnimation;
+            updateAnim();
+            if (!mAllowAnimation && mAnim != null) {
+                // Reset drawable such that we show the first frame whenever we're not animating.
+                mAnim.setVisible(getVisibility() == VISIBLE, true /* restart */);
+            }
+        }
+    }
+
     private void updateAnim() {
         Drawable drawable = getDrawable();
         if (mAttached && mAnim != null) {
@@ -63,7 +75,7 @@
         }
         if (drawable instanceof AnimationDrawable) {
             mAnim = (AnimationDrawable) drawable;
-            if (isShown()) {
+            if (isShown() && mAllowAnimation) {
                 mAnim.start();
             }
         } else {
@@ -114,7 +126,7 @@
     protected void onVisibilityChanged(View changedView, int vis) {
         super.onVisibilityChanged(changedView, vis);
         if (mAnim != null) {
-            if (isShown()) {
+            if (isShown() && mAllowAnimation) {
                 mAnim.start();
             } else {
                 mAnim.stop();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index ba34ac1..cb2aa94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -39,12 +39,11 @@
 import android.view.animation.Interpolator;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
 import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.drawable.GradientDrawable;
-
 /**
  * A view which can draw a scrim
  */
@@ -94,6 +93,11 @@
         mColors = new ColorExtractor.GradientColors();
         updateScreenSize();
         updateColorWithTint(false);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
 
         // We need to know about configuration changes to update the gradient size
         // since it's independent from view bounds.
@@ -102,6 +106,14 @@
     }
 
     @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        ConfigurationController config = Dependency.get(ConfigurationController.class);
+        config.removeCallback(this);
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         if (mDrawAsSrc || mDrawable.getAlpha() > 0) {
             if (!mHasExcludedArea) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 89694b33..05d47ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -756,9 +756,16 @@
             updateIconScale();
             updateDecorColor();
             updateIconColor();
+            updateAllowAnimation();
         }, dark, fade, delay);
     }
 
+    private void updateAllowAnimation() {
+        if (mDarkAmount == 0 || mDarkAmount == 1) {
+            setAllowAnimation(mDarkAmount == 0);
+        }
+    }
+
     public interface OnVisibilityChangedListener {
         void onVisibilityChanged(int newVisibility);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 6b276f8..f591524 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -54,6 +54,7 @@
     private float mBehindTarget;
     private boolean mDozingAborted;
     private boolean mWakeAndUnlocking;
+    private boolean mFullyPulsing;
 
     public DozeScrimController(ScrimController scrimController, Context context) {
         mContext = context;
@@ -136,6 +137,12 @@
         abortPulsing();
     }
 
+    public void pulseOutNow() {
+        if (mPulseCallback != null && mFullyPulsing) {
+            mPulseOut.run();
+        }
+    }
+
     public void onScreenTurnedOn() {
         if (isPulsing()) {
             final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
@@ -163,6 +170,7 @@
         if (DEBUG) Log.d(TAG, "Cancel pulsing");
 
         if (mPulseCallback != null) {
+            mFullyPulsing = false;
             mHandler.removeCallbacks(mPulseIn);
             mHandler.removeCallbacks(mPulseOut);
             mHandler.removeCallbacks(mPulseOutExtended);
@@ -297,6 +305,7 @@
             mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
             mHandler.postDelayed(mPulseOutExtended,
                     mDozeParameters.getPulseVisibleDurationExtended());
+            mFullyPulsing = true;
         }
     };
 
@@ -311,6 +320,8 @@
     private final Runnable mPulseOut = new Runnable() {
         @Override
         public void run() {
+            mFullyPulsing = false;
+            mHandler.removeCallbacks(mPulseOut);
             mHandler.removeCallbacks(mPulseOutExtended);
             if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
             if (!mDozing) return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 6cb722f..5af80f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -163,8 +163,8 @@
             }
             mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
                     FINGERPRINT_WAKELOCK_TIMEOUT_MS);
-            if (mDozeScrimController.isPulsing()) {
 
+            if (pulsingOrAod()) {
                 // If we are waking the device up while we are pulsing the clock and the
                 // notifications would light up first, creating an unpleasant animation.
                 // Defer changing the screen brightness by forcing doze brightness on our window
@@ -175,6 +175,12 @@
         Trace.endSection();
     }
 
+    private boolean pulsingOrAod() {
+        boolean pulsing = mDozeScrimController.isPulsing();
+        boolean dozingWithScreenOn = mStatusBar.isDozing() && !mStatusBar.isScreenFullyOff();
+        return pulsing || dozingWithScreenOn;
+    }
+
     @Override
     public void onFingerprintAuthenticated(int userId) {
         Trace.beginSection("FingerprintUnlockController#onFingerprintAuthenticated");
@@ -263,16 +269,23 @@
         Trace.endSection();
     }
 
+    public boolean hasPendingAuthentication() {
+        return mPendingAuthenticatedUserId != -1
+                && mUpdateMonitor.isUnlockingWithFingerprintAllowed()
+                && mPendingAuthenticatedUserId == KeyguardUpdateMonitor.getCurrentUser();
+    }
+
     public int getMode() {
         return mMode;
     }
 
     private int calculateMode() {
         boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithFingerprintAllowed();
+
         if (!mUpdateMonitor.isDeviceInteractive()) {
             if (!mStatusBarKeyguardViewManager.isShowing()) {
                 return MODE_ONLY_WAKE;
-            } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
+            } else if (pulsingOrAod() && unlockingAllowed) {
                 return MODE_WAKE_AND_UNLOCK_PULSING;
             } else if (unlockingAllowed || !mUnlockMethodCache.isMethodSecure()) {
                 return MODE_WAKE_AND_UNLOCK;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 674a61c..df1ffda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -168,8 +168,7 @@
                         distance = mTranslationOnDown + distance;
                         distance = Math.max(0, distance);
                     }
-                    setTranslation(distance, false /* isReset */, false /* animateReset */,
-                            false /* force */);
+                    setTranslation(distance, false /* isReset */, false /* animateReset */);
                 }
                 break;
 
@@ -374,12 +373,11 @@
         targetView.finishAnimation(velocity, mAnimationEndRunnable);
     }
 
-    private void setTranslation(float translation, boolean isReset, boolean animateReset,
-            boolean force) {
+    private void setTranslation(float translation, boolean isReset, boolean animateReset) {
         translation = rightSwipePossible() ? translation : Math.max(0, translation);
         translation = leftSwipePossible() ? translation : Math.min(0, translation);
         float absTranslation = Math.abs(translation);
-        if (translation != mTranslation || isReset || force) {
+        if (translation != mTranslation || isReset) {
             KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon;
             KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon;
             float alpha = absTranslation / getMinTranslationAmount();
@@ -394,15 +392,15 @@
             boolean slowAnimation = isReset && isBelowFalsingThreshold();
             if (!isReset) {
                 updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(),
-                        false, false, force, false);
+                        false, false, false, false);
             } else {
                 updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(),
-                        animateIcons, slowAnimation, force, forceNoCircleAnimation);
+                        animateIcons, slowAnimation, true /* isReset */, forceNoCircleAnimation);
             }
             updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(),
-                    animateIcons, slowAnimation, force, forceNoCircleAnimation);
+                    animateIcons, slowAnimation, isReset, forceNoCircleAnimation);
             updateIcon(mCenterIcon, 0.0f, fadeOutAlpha * mCenterIcon.getRestingAlpha(),
-                    animateIcons, slowAnimation, force, forceNoCircleAnimation);
+                    animateIcons, slowAnimation, isReset, forceNoCircleAnimation);
 
             mTranslation = translation;
         }
@@ -510,12 +508,8 @@
     }
 
     public void reset(boolean animate) {
-        reset(animate, false /* force */);
-    }
-
-    public void reset(boolean animate, boolean force) {
         cancelAnimation();
-        setTranslation(0.0f, true, animate, force);
+        setTranslation(0.0f, true /* isReset */, animate);
         mMotionCancelled = true;
         if (mSwipingInProgress) {
             mCallback.onSwipingAborted();
@@ -523,10 +517,6 @@
         }
     }
 
-    public void resetImmediately() {
-        reset(false /* animate */, true /* force */);
-    }
-
     public boolean isSwipingInProgress() {
         return mSwipingInProgress;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index a4dfcd8..a3e5e45 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -126,6 +126,7 @@
     private TextView mEnterpriseDisclosure;
     private TextView mIndicationText;
     private ViewGroup mPreviewContainer;
+    private ViewGroup mOverlayContainer;
 
     private View mLeftPreview;
     private View mCameraPreview;
@@ -229,6 +230,7 @@
         super.onFinishInflate();
         mLockPatternUtils = new LockPatternUtils(mContext);
         mPreviewContainer = findViewById(R.id.preview_container);
+        mOverlayContainer = findViewById(R.id.overlay_container);
         mRightAffordanceView = findViewById(R.id.camera_button);
         mLeftAffordanceView = findViewById(R.id.left_button);
         mLockIcon = findViewById(R.id.lock_icon);
@@ -254,6 +256,7 @@
         mFlashlightController = Dependency.get(FlashlightController.class);
         mAccessibilityController = Dependency.get(AccessibilityController.class);
         mAssistManager = Dependency.get(AssistManager.class);
+        mLockIcon.setAccessibilityController(mAccessibilityController);
         updateLeftAffordance();
     }
 
@@ -820,8 +823,10 @@
 
         if (dozing) {
             mLockIcon.setVisibility(INVISIBLE);
+            mOverlayContainer.setVisibility(INVISIBLE);
         } else {
             mLockIcon.setVisibility(VISIBLE);
+            mOverlayContainer.setVisibility(VISIBLE);
             if (animate) {
                 startFinishDozeAnimation();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 6f2c6e0..4e79314b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -266,13 +266,17 @@
         parent.addView(v);
         addToDispatchers(v);
         View lastView = landscape ? mLastLandscape : mLastPortrait;
+        View accessibilityView = v;
+        if (v instanceof ReverseFrameLayout) {
+            accessibilityView = ((ReverseFrameLayout) v).getChildAt(0);
+        }
         if (lastView != null) {
-            v.setAccessibilityTraversalAfter(lastView.getId());
+            accessibilityView.setAccessibilityTraversalAfter(lastView.getId());
         }
         if (landscape) {
-            mLastLandscape = v;
+            mLastLandscape = accessibilityView;
         } else {
-            mLastPortrait = v;
+            mLastPortrait = accessibilityView;
         }
         return v;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 9662078..3940a15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -346,6 +346,9 @@
         addView(mKeyguardBottomArea, index);
         initBottomArea();
         setDarkAmount(mDarkAmount);
+
+        setKeyguardStatusViewVisibility(mStatusBarState, false, false);
+        setKeyguardBottomAreaVisibility(mStatusBarState, false);
     }
 
     private void initBottomArea() {
@@ -2561,7 +2564,7 @@
     public void setTouchDisabled(boolean disabled) {
         super.setTouchDisabled(disabled);
         if (disabled && mAffordanceHelper.isSwipingInProgress() && !mIsLaunchTransitionRunning) {
-            mAffordanceHelper.resetImmediately();
+            mAffordanceHelper.reset(false /* animate */);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 754c344..66dbdd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -33,6 +33,9 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -43,9 +46,6 @@
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.stack.ViewState;
 
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.ColorExtractor.OnColorsChangedListener;
-
 /**
  * Controls both the scrim behind the notifications and in front of the notifications (when a
  * security method gets shown).
@@ -80,8 +80,8 @@
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
     private final SysuiColorExtractor mColorExtractor;
-    private ColorExtractor.GradientColors mLockColors;
-    private ColorExtractor.GradientColors mSystemColors;
+    private GradientColors mLockColors;
+    private GradientColors mSystemColors;
     private boolean mNeedsDrawableColorUpdate;
 
     protected float mScrimBehindAlpha;
@@ -304,8 +304,8 @@
             mNeedsDrawableColorUpdate = false;
             if (mKeyguardShowing) {
                 // Always animate color changes if we're seeing the keyguard
-                mScrimInFront.setColors(mLockColors);
-                mScrimBehind.setColors(mLockColors);
+                mScrimInFront.setColors(mLockColors, true /* animated */);
+                mScrimBehind.setColors(mLockColors, true /* animated */);
             } else {
                 // Only animate scrim color if the scrim view is actually visible
                 boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
@@ -617,9 +617,9 @@
         return alpha * expandFactor;
     }
 
-    public void forceHideScrims(boolean hide) {
+    public void forceHideScrims(boolean hide, boolean animated) {
         mForceHideScrims = hide;
-        mAnimateChange = false;
+        mAnimateChange = animated;
         scheduleUpdate();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index 7a7efbd..d537cda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -230,18 +230,19 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
+        final float width = getBounds().width();
+        final float height = getBounds().height();
+
         boolean isRtl = getLayoutDirection() == LayoutDirection.RTL;
         if (isRtl) {
             canvas.save();
             // Mirror the drawable
-            canvas.translate(canvas.getWidth(), 0);
+            canvas.translate(width, 0);
             canvas.scale(-1.0f, 1.0f);
         }
         mFullPath.reset();
         mFullPath.setFillType(FillType.WINDING);
 
-        final float width = getBounds().width();
-        final float height = getBounds().height();
         final float padding = Math.round(PAD * width);
         final float cornerRadius = RADIUS_RATIO * height;
         // Offset from circle where the hypotenuse meets the circle
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 12e9c009..e0dbcc6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -139,6 +139,7 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.graphics.ColorUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -244,8 +245,6 @@
 import com.android.systemui.util.leak.LeakDetector;
 import com.android.systemui.volume.VolumeComponent;
 
-import com.google.android.colorextraction.ColorExtractor;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -737,6 +736,7 @@
     private HashMap<String, Entry> mPendingNotifications = new HashMap<>();
     private boolean mClearAllEnabled;
     @Nullable private View mAmbientIndicationContainer;
+    private String mKeyToRemoveOnGutsClosed;
     private SysuiColorExtractor mColorExtractor;
     private ForegroundServiceController mForegroundServiceController;
 
@@ -1023,6 +1023,7 @@
                     mStatusBarView.setBar(this);
                     mStatusBarView.setPanel(mNotificationPanel);
                     mStatusBarView.setScrimController(mScrimController);
+                    mStatusBarView.setBouncerShowing(mBouncerShowing);
                     setAreThereNotifications();
                     checkBarModes();
                 }).getFragmentManager()
@@ -1156,7 +1157,8 @@
                             .build());
             final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
                     mIconController);
-            mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
+            mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow,
+                    mScrimController);
             fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
                 QS qs = (QS) f;
                 if (qs instanceof QSFragment) {
@@ -1322,6 +1324,9 @@
         if (mBrightnessMirrorController != null) {
             mBrightnessMirrorController.onOverlayChanged();
         }
+        if (mStatusBarKeyguardViewManager != null) {
+            mStatusBarKeyguardViewManager.onOverlayChanged();
+        }
     }
 
     protected void reevaluateStyles() {
@@ -1787,6 +1792,13 @@
             mRemoteInputEntriesToRemoveOnCollapse.add(entry);
             return;
         }
+        if (entry != null && mNotificationGutsExposed != null
+                && mNotificationGutsExposed == entry.row.getGuts()) {
+            Log.w(TAG, "Keeping notification because it's showing guts. " + key);
+            mLatestRankingMap = ranking;
+            mKeyToRemoveOnGutsClosed = key;
+            return;
+        }
 
         if (entry != null) {
             mForegroundServiceController.removeNotification(entry.notification);
@@ -1875,6 +1887,11 @@
         } catch (RemoteException ex) {
             // system process is dead if we're here.
         }
+        if (mStackScroller.hasPulsingNotifications() && mHeadsUpManager.getAllEntries().isEmpty()) {
+            // We were showing a pulse for a notification, but no notifications are pulsing anymore.
+            // Finish the pulse.
+            mDozeScrimController.pulseOutNow();
+        }
         // end old BaseStatusBar.performRemoveNotification.
     }
 
@@ -3472,6 +3489,8 @@
         pw.println(Settings.Global.zenModeToString(mZenMode));
         pw.print("  mUseHeadsUp=");
         pw.println(mUseHeadsUp);
+        pw.print("  mKeyToRemoveOnGutsClosed=");
+        pw.println(mKeyToRemoveOnGutsClosed);
         if (mStatusBarView != null) {
             dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
         }
@@ -3770,7 +3789,7 @@
 
     // SystemUIService notifies SystemBars of configuration changes, which then calls down here
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
+    public void onConfigChanged(Configuration newConfig) {
         updateResources();
         updateDisplaySize(); // populates mDisplayMetrics
 
@@ -4264,7 +4283,7 @@
         releaseGestureWakeLock();
         runLaunchTransitionEndRunnable();
         mLaunchTransitionFadingAway = false;
-        mScrimController.forceHideScrims(false /* hide */);
+        mScrimController.forceHideScrims(false /* hide */, false /* animated */);
         updateMediaMetaData(true /* metaDataChanged */, true);
     }
 
@@ -4299,7 +4318,7 @@
                 if (beforeFading != null) {
                     beforeFading.run();
                 }
-                mScrimController.forceHideScrims(true /* hide */);
+                mScrimController.forceHideScrims(true /* hide */, false /* animated */);
                 updateMediaMetaData(false, true);
                 mNotificationPanel.setAlpha(1);
                 mStackScroller.setParentNotFullyVisible(true);
@@ -4569,18 +4588,10 @@
         final boolean useDarkText = mColorExtractor.getColors(which, true /* ignoreVisibility */)
                 .supportsDarkText();
         // And wallpaper defines if QS should be light or dark.
-        boolean useDarkTheme = false;
-        final WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
-        if (wallpaperManager != null) {
-            WallpaperColors wallpaperColors = wallpaperManager
-                    .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-            if (wallpaperColors != null) {
-                final int mainColor = wallpaperColors.getPrimaryColor().toArgb();
-                final float[] hsl = new float[3];
-                ColorUtils.colorToHSL(mainColor, hsl);
-                useDarkTheme = hsl[2] < 0.2f;
-            }
-        }
+        WallpaperColors systemColors = mColorExtractor
+                .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+        final boolean useDarkTheme = systemColors != null
+                && (systemColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
 
         // Enable/disable dark UI.
         if (isUsingDarkTheme() != useDarkTheme) {
@@ -5104,7 +5115,7 @@
 
     public void setBouncerShowing(boolean bouncerShowing) {
         mBouncerShowing = bouncerShowing;
-        mStatusBarView.setBouncerShowing(bouncerShowing);
+        if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
         recomputeDisableFlags(true /* animate */);
     }
 
@@ -5174,6 +5185,14 @@
         mDozeScrimController.onScreenTurnedOn();
     }
 
+    /**
+     * @return true if the screen is currently fully off, i.e. has finished turning off and has
+     *         since not started turning on.
+     */
+    public boolean isScreenFullyOff() {
+        return mScreenFullyOff;
+    }
+
     @Override
     public void showScreenPinningRequest(int taskId) {
         if (mKeyguardMonitor.isShowing()) {
@@ -5382,6 +5401,21 @@
         }
 
         @Override
+        public boolean isProvisioned() {
+            return mDeviceProvisionedController.isDeviceProvisioned()
+                    && mDeviceProvisionedController.isCurrentUserSetup();
+        }
+
+        @Override
+        public boolean isBlockingDoze() {
+            if (mFingerprintUnlockController.hasPendingAuthentication()) {
+                Log.i(TAG, "Blocking AOD because fingerprint has authenticated");
+                return true;
+            }
+            return false;
+        }
+
+        @Override
         public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
             StatusBar.this.startPendingIntentDismissingKeyguard(intent);
         }
@@ -5415,6 +5449,11 @@
             }
         }
 
+        @Override
+        public void setDozeScreenBrightness(int value) {
+            mStatusBarWindowManager.setDozeScreenBrightness(value);
+        }
+
         public void dispatchDoubleTap(float viewX, float viewY) {
             dispatchTap(mAmbientIndicationContainer, viewX, viewY);
             dispatchTap(mAmbientIndicationContainer, viewX, viewY);
@@ -6123,6 +6162,11 @@
                 mNotificationGutsExposed = null;
                 mGutsMenuItem = null;
             }
+            String key = sbn.getKey();
+            if (key.equals(mKeyToRemoveOnGutsClosed)) {
+                mKeyToRemoveOnGutsClosed = null;
+                removeNotification(key, mLatestRankingMap);
+            }
         });
 
         View gutsView = item.getGutsView();
@@ -7082,9 +7126,12 @@
         Entry entry = mNotificationData.get(key);
         if (entry == null) {
             return;
-        } else {
-            mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
-            mRemoteInputEntriesToRemoveOnCollapse.remove(entry);
+        }
+        mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
+        mRemoteInputEntriesToRemoveOnCollapse.remove(entry);
+        if (key.equals(mKeyToRemoveOnGutsClosed)) {
+            mKeyToRemoveOnGutsClosed = null;
+            Log.w(TAG, "Notification that was kept for guts was updated. " + key);
         }
 
         Notification n = notification.getNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 2833ff1..be338de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -416,6 +416,10 @@
         mBouncer.hide(true /* destroyView */);
     }
 
+    public void onOverlayChanged() {
+        mBouncer.hide(true /* destroyView */);
+    }
+
     private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
             boolean skipFirstFrame) {
         animateScrimControllerKeyguardFadingOut(delay, duration, null /* endRunnable */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 0566361..debba49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -58,7 +58,7 @@
     private boolean mHasTopUiChanged;
     private int mBarHeight;
     private final boolean mKeyguardScreenRotation;
-    private final float mScreenBrightnessDoze;
+    private float mScreenBrightnessDoze;
     private final State mCurrentState = new State();
     private OtherwisedCollapsedListener mListener;
 
@@ -110,6 +110,10 @@
         mLpChanged.copyFrom(mLp);
     }
 
+    public void setDozeScreenBrightness(int value) {
+        mScreenBrightnessDoze = value / 255f;
+    }
+
     public void setKeyguardDark(boolean dark) {
         int vis = mStatusBarView.getSystemUiVisibility();
         if (dark) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
index d5a91bb..e8a456e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
@@ -31,6 +31,7 @@
 import android.graphics.drawable.Drawable;
 import android.view.animation.Interpolator;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 
@@ -82,7 +83,7 @@
 
         mPaint = new Paint();
         mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setColor(Color.WHITE);
+        mPaint.setColor(Utils.getColorAttr(context, R.attr.bgProtectTextColor));
         mPaint.setAntiAlias(true);
         mPaint.setStrokeWidth(mThickness);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index dc4b115..fc74952 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -75,6 +75,8 @@
     @Override
     public boolean canConfigBluetooth() {
         return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH,
+                UserHandle.of(mCurrentUser))
+            && !mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH,
                 UserHandle.of(mCurrentUser));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index ab55b23..718c348 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -24,6 +24,7 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
@@ -37,30 +38,31 @@
     public long TRANSITION_DURATION_IN = 200;
 
     private final StatusBarWindowView mStatusBarWindow;
-    private final ScrimView mScrimBehind;
+    private final ScrimController mScrimController;
     private final View mNotificationPanel;
     private final int[] mInt2Cache = new int[2];
     private View mBrightnessMirror;
 
-    public BrightnessMirrorController(StatusBarWindowView statusBarWindow) {
+    public BrightnessMirrorController(StatusBarWindowView statusBarWindow,
+            ScrimController scrimController) {
         mStatusBarWindow = statusBarWindow;
-        mScrimBehind = (ScrimView) statusBarWindow.findViewById(R.id.scrim_behind);
         mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror);
         mNotificationPanel = statusBarWindow.findViewById(R.id.notification_panel);
         mStackScroller = (NotificationStackScrollLayout) statusBarWindow.findViewById(
                 R.id.notification_stack_scroller);
+        mScrimController = scrimController;
     }
 
     public void showMirror() {
         mBrightnessMirror.setVisibility(View.VISIBLE);
         mStackScroller.setFadingOut(true);
-        mScrimBehind.animateViewAlpha(0.0f, TRANSITION_DURATION_OUT, Interpolators.ALPHA_OUT);
+        mScrimController.forceHideScrims(true /* hide */, true /* animated */);
         outAnimation(mNotificationPanel.animate())
                 .withLayer();
     }
 
     public void hideMirror() {
-        mScrimBehind.animateViewAlpha(1.0f, TRANSITION_DURATION_IN, Interpolators.ALPHA_IN);
+        mScrimController.forceHideScrims(false /* hide */, true /* animated */);
         inAnimation(mNotificationPanel.animate())
                 .withLayer()
                 .withEndAction(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 2d3e0b6..d652bde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -228,7 +228,9 @@
                 setPressed(false);
                 // Always send a release ourselves because it doesn't seem to be sent elsewhere
                 // and it feels weird to sometimes get a release haptic and other times not.
-                performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
+                if ((SystemClock.uptimeMillis() - mDownTime) > 100) {
+                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
+                }
                 if (mCode != 0) {
                     if (doIt) {
                         sendEvent(KeyEvent.ACTION_UP, 0);
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 9d197d7..74523e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -3362,15 +3362,29 @@
         if (!mIsExpanded) {
             setOwnScrollY(0);
             mStatusBar.resetUserExpandedStates();
+            clearTemporaryViews();
+            clearUserLockedViews();
+        }
+    }
 
-            // lets make sure nothing is in the overlay / transient anymore
-            clearTemporaryViews(this);
-            for (int i = 0; i < getChildCount(); i++) {
-                ExpandableView child = (ExpandableView) getChildAt(i);
-                if (child instanceof ExpandableNotificationRow) {
-                    ExpandableNotificationRow row = (ExpandableNotificationRow) child;
-                    clearTemporaryViews(row.getChildrenContainer());
-                }
+    private void clearUserLockedViews() {
+        for (int i = 0; i < getChildCount(); i++) {
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            if (child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                row.setUserLocked(false);
+            }
+        }
+    }
+
+    private void clearTemporaryViews() {
+        // lets make sure nothing is in the overlay / transient anymore
+        clearTemporaryViews(this);
+        for (int i = 0; i < getChildCount(); i++) {
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            if (child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                clearTemporaryViews(row.getChildrenContainer());
             }
         }
     }
@@ -3405,6 +3419,7 @@
         if (changed) {
             if (!mIsExpanded) {
                 mGroupManager.collapseAllGroups();
+                mExpandHelper.cancelImmediately();
             }
             updateNotificationAnimationStates();
             updateChronometers();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 9c69b98..474a9a4 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -33,8 +33,6 @@
         PreferenceFragment.OnPreferenceStartFragmentCallback,
         PreferenceFragment.OnPreferenceStartScreenCallback {
 
-    static final String ACTIVITY_ALIAS_NAME = "com.android.systemui.tuner.TunerSettingLink";
-
     private static final String TAG_TUNER = "tuner";
 
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index 369ce69..3a9d1c7 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -68,12 +68,6 @@
                 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                         : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                 PackageManager.DONT_KILL_APP);
-
-        userContext(context).getPackageManager().setComponentEnabledSetting(
-                new ComponentName(context, TunerActivity.ACTIVITY_ALIAS_NAME),
-                enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-                        : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
     }
 
     public static final boolean isTunerEnabled(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 2b2ad69..2527c6b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -25,7 +25,6 @@
 import android.annotation.SuppressLint;
 import android.app.Dialog;
 import android.app.KeyguardManager;
-import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
@@ -33,7 +32,6 @@
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.ColorDrawable;
@@ -72,21 +70,19 @@
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
+
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.VolumeDialog;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.plugins.VolumeDialogController.State;
 import com.android.systemui.plugins.VolumeDialogController.StreamState;
-import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerZenModePanel;
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.drawable.GradientDrawable;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index ecdea4f..4716552 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -144,7 +144,7 @@
         super(context, attrs);
         mContext = context;
         mPrefs = new ZenPrefs();
-        mInflater = LayoutInflater.from(mContext.getApplicationContext());
+        mInflater = LayoutInflater.from(mContext);
         mForeverId = Condition.newId(mContext).appendPath("forever").build();
         mConfigurableTexts = new ConfigurableTexts(mContext);
         mVoiceCapable = Util.isVoiceCapable(mContext);
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 136aaad..5e71dd4 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -45,8 +45,7 @@
     android-support-v7-mediarouter \
     android-support-v7-palette \
     android-support-v14-preference \
-    android-support-v17-leanback \
-    colorextraction
+    android-support-v17-leanback
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     metrics-helper-lib \
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 9bb2180..f24e7b5 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -38,6 +38,7 @@
     <uses-permission android:name="android.permission.CONTROL_VPN" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
index 1ed5f56..a81188a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -23,19 +23,14 @@
 import android.graphics.Color;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.util.Pair;
 
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.types.Tonal;
 import com.android.systemui.SysuiTestCase;
 
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.types.Tonal;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Tests color extraction generation.
  */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index 2345110..641f263 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -72,6 +72,16 @@
     }
 
     @Override
+    public boolean isProvisioned() {
+        return false;
+    }
+
+    @Override
+    public boolean isBlockingDoze() {
+        return false;
+    }
+
+    @Override
     public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
         throw new RuntimeException("not implemented");
     }
@@ -96,4 +106,8 @@
         doubleTapX = y;
         doubleTapY = y;
     }
+
+    @Override
+    public void setDozeScreenBrightness(int value) {
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 27d781d..c016a851 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -29,6 +29,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.policy.BluetoothController;
+
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
@@ -52,6 +54,7 @@
 
     @Before
     public void setUp() throws Exception {
+        mDependency.injectMockDependency(BluetoothController.class);
         mManagers = new ArrayList<>();
         QSTileHost host = new QSTileHost(mContext, null,
                 mock(StatusBarIconController.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
index 0886780..4c3bf10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
@@ -28,14 +28,17 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.testing.AndroidTestingRunner;
 import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.ViewUtils;
 import android.view.View;
 
-import com.android.systemui.SysuiTestCase;
-
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.drawable.GradientDrawable;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,18 +46,28 @@
 
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class ScrimViewTest extends SysuiTestCase {
+public class ScrimViewTest extends LeakCheckedTest {
 
     ScrimView mView;
 
     @Before
     public void setUp() {
+        injectLeakCheckedDependency(ConfigurationController.class);
         mView = new ScrimView(getContext());
         mView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
         mView.layout(0, 0, 1920, 1080);
     }
 
     @Test
+    @RunWithLooper
+    public void testAttachDetach() {
+        ViewUtils.attachView(mView);
+        TestableLooper.get(this).processAllMessages();
+        ViewUtils.detachView(mView);
+        TestableLooper.get(this).processAllMessages();
+    }
+
+    @Test
     public void testSetDrawable_UpdateDrawable() {
         Drawable drawable = new ColorDrawable(Color.GREEN);
         mView.setDrawable(drawable);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
index 1b42d1b..e7e6829 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
@@ -28,7 +28,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.service.notification.StatusBarNotification;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
@@ -40,9 +39,9 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationTestHelper;
-import com.android.systemui.statusbar.InflationTask;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -150,6 +149,7 @@
     }
 
     @Test
+    @Ignore
     public void testInflationIsRetriedIfAsyncFails() throws Exception {
         NotificationInflater.InflationProgress result =
                 new NotificationInflater.InflationProgress();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 0937ce2..c0de004 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -19,12 +19,13 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
 import com.android.internal.app.NightDisplayController;
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
-
-import android.support.test.filters.SmallTest;
-import android.testing.AndroidTestingRunner;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.qs.QSTileHost;
 
@@ -35,6 +36,7 @@
 import org.mockito.Mockito;
 
 @RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 @SmallTest
 public class AutoTileManagerTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 17ca924..8a4983c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -67,6 +67,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationData.Entry;
@@ -156,6 +157,12 @@
     }
 
     @Test
+    public void testSetBouncerShowing_noCrash() {
+        mStatusBar.mCommandQueue = mock(CommandQueue.class);
+        mStatusBar.setBouncerShowing(true);
+    }
+
+    @Test
     public void executeRunnableDismissingKeyguard_nullRunnable_showingAndOccluded() {
         when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
         when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 8d106b4..b88ee44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -18,6 +18,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
+@Ignore("Flaky")
 public class NetworkControllerDataTest extends NetworkControllerBaseTest {
 
     @Test
@@ -106,7 +107,6 @@
                 TelephonyIcons.QS_DATA_4G);
     }
 
-    @Ignore("Flaky")
     @Test
     public void testDataDisabledIcon() {
         setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index cba9f77..97a4061 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -32,6 +32,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.SignalDrawable;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -47,6 +48,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
+@Ignore("Flaky")
 public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java
new file mode 100644
index 0000000..9ef30c3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 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.utils.leaks;
+
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+public class FakeConfigurationController
+        extends BaseLeakChecker<ConfigurationController.ConfigurationListener>
+        implements ConfigurationController {
+
+    public FakeConfigurationController(LeakCheckedTest.SysuiLeakCheck sysuiLeakCheck) {
+        super(sysuiLeakCheck, "config");
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
index 94af7733..ecda9620 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
@@ -26,6 +26,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.ConfigurationController;
 import com.android.systemui.statusbar.policy.FlashlightController;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -68,6 +69,7 @@
             PluginManager.class,
             TunerService.class,
             StatusBarIconController.class,
+            ConfigurationController.class,
     };
 
     @Rule
@@ -134,6 +136,8 @@
                     obj = new FakeTunerService(this);
                 } else if (cls == StatusBarIconController.class) {
                     obj = new FakeStatusBarIconController(this);
+                } else if (cls == ConfigurationController.class) {
+                    obj = new FakeConfigurationController(this);
                 } else {
                     Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet");
                 }
diff --git a/packages/WallpaperCropper/Android.mk b/packages/WallpaperCropper/Android.mk
index 09b41fd..0254673 100644
--- a/packages/WallpaperCropper/Android.mk
+++ b/packages/WallpaperCropper/Android.mk
@@ -6,7 +6,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_JAVA_LIBRARIES := telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
 
 LOCAL_PACKAGE_NAME := WallpaperCropper
 LOCAL_CERTIFICATE := platform
diff --git a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
index c4e493b..9501073 100644
--- a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
+++ b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
@@ -20,7 +20,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.support.v4.util.LongSparseArray;
+import android.util.LongSparseArray;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pools.Pool;
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 0a0fa18..adcc8eb 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4190,6 +4190,12 @@
     // OS: O DR
     FIELD_TIME_ELAPSED_BETWEEN_CHARGE_MS = 1030;
 
+    // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
+    // -> Forget button.
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    DIALOG_BLUETOOTH_PAIRED_DEVICE_FORGET = 1031;
+
     // ---- End O-DR1 Constants, all O-DR1 constants go above this line ----
 
     // ACTION: Settings > Network & Internet > Mobile network > Mobile data
@@ -4202,6 +4208,11 @@
     // OS: O MR
     ACTION_MOBILE_NETWORK_DATA_USAGE = 1082;
 
+    // FIELD - State of asynchronous ranking when Settings search result is clicked
+    // CATEGORY: SETTINGS
+    // OS: O MR
+    FIELD_SETTINGS_SEARCH_RESULT_ASYNC_RANKING_STATE = 1083;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 0e42e6d..7324b82 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -17,6 +17,7 @@
 package com.android.server.accessibility;
 
 import android.content.Context;
+import android.os.Handler;
 import android.os.PowerManager;
 import android.util.Pools.SimplePool;
 import android.util.Slog;
@@ -30,6 +31,8 @@
 import android.view.WindowManagerPolicy;
 import android.view.accessibility.AccessibilityEvent;
 
+import com.android.server.LocalServices;
+
 /**
  * This class is an input filter for implementing accessibility features such
  * as display magnification and explore by touch.
@@ -425,7 +428,8 @@
         }
 
         if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) {
-            mKeyboardInterceptor = new KeyboardInterceptor(mAms);
+            mKeyboardInterceptor = new KeyboardInterceptor(mAms,
+                    LocalServices.getService(WindowManagerPolicy.class));
             addFirstEventHandler(mKeyboardInterceptor);
         }
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index a58ba09..a59844d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -102,6 +102,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.DumpUtils;
@@ -903,7 +904,8 @@
         }
     }
 
-    boolean notifyKeyEvent(KeyEvent event, int policyFlags) {
+    @VisibleForTesting
+    public boolean notifyKeyEvent(KeyEvent event, int policyFlags) {
         synchronized (mLock) {
             List<Service> boundServices = getCurrentUserStateLocked().mBoundServices;
             if (boundServices.isEmpty()) {
diff --git a/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java b/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java
index bbb25af..f00a954 100644
--- a/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java
+++ b/services/accessibility/java/com/android/server/accessibility/KeyboardInterceptor.java
@@ -16,19 +16,52 @@
 
 package com.android.server.accessibility;
 
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Pools;
+import android.util.Slog;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.WindowManagerPolicy;
 import android.view.accessibility.AccessibilityEvent;
 
 /**
  * Intercepts key events and forwards them to accessibility manager service.
  */
-public class KeyboardInterceptor implements EventStreamTransformation {
-    private EventStreamTransformation mNext;
-    private AccessibilityManagerService mAms;
+public class KeyboardInterceptor implements EventStreamTransformation, Handler.Callback {
+    private static final int MESSAGE_PROCESS_QUEUED_EVENTS = 1;
+    private static final String LOG_TAG = "KeyboardInterceptor";
 
-    public KeyboardInterceptor(AccessibilityManagerService service) {
+    private final AccessibilityManagerService mAms;
+    private final WindowManagerPolicy mPolicy;
+    private final Handler mHandler;
+
+    private EventStreamTransformation mNext;
+    private KeyEventHolder mEventQueueStart;
+    private KeyEventHolder mEventQueueEnd;
+
+    /**
+     * @param service The service to notify of key events
+     * @param policy The policy to check for keys that may affect a11y
+     */
+    public KeyboardInterceptor(AccessibilityManagerService service, WindowManagerPolicy policy) {
         mAms = service;
+        mPolicy = policy;
+        mHandler = new Handler(this);
+    }
+
+    /**
+     * @param service The service to notify of key events
+     * @param policy The policy to check for keys that may affect a11y
+     * @param handler The handler to use. Only used for testing.
+     */
+    public KeyboardInterceptor(AccessibilityManagerService service, WindowManagerPolicy policy,
+            Handler handler) {
+        // Can't combine the constructors without making at least mHandler non-final.
+        mAms = service;
+        mPolicy = policy;
+        mHandler = handler;
     }
 
     @Override
@@ -40,6 +73,19 @@
 
     @Override
     public void onKeyEvent(KeyEvent event, int policyFlags) {
+        /*
+         * Certain keys have system-level behavior that affects accessibility services.
+         * Let that behavior settle before handling the keys
+         */
+        long eventDelay = getEventDelay(event, policyFlags);
+        if (eventDelay < 0) {
+            return;
+        }
+        if ((eventDelay > 0) || (mEventQueueStart != null))  {
+            addEventToQueue(event, policyFlags, eventDelay);
+            return;
+        }
+
         mAms.notifyKeyEvent(event, policyFlags);
     }
 
@@ -65,4 +111,104 @@
     @Override
     public void onDestroy() {
     }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        if (msg.what != MESSAGE_PROCESS_QUEUED_EVENTS) {
+            Slog.e(LOG_TAG, "Unexpected message type");
+            return false;
+        }
+        processQueuedEvents();
+        if (mEventQueueStart != null) {
+            scheduleProcessQueuedEvents();
+        }
+        return true;
+    }
+
+    private void addEventToQueue(KeyEvent event, int policyFlags, long delay) {
+        long dispatchTime = SystemClock.uptimeMillis() + delay;
+        if (mEventQueueStart == null) {
+            mEventQueueEnd = mEventQueueStart =
+                    KeyEventHolder.obtain(event, policyFlags, dispatchTime);
+            scheduleProcessQueuedEvents();
+            return;
+        }
+        final KeyEventHolder holder = KeyEventHolder.obtain(event, policyFlags, dispatchTime);
+        holder.next = mEventQueueStart;
+        mEventQueueStart.previous = holder;
+        mEventQueueStart = holder;
+    }
+
+    private void scheduleProcessQueuedEvents() {
+        if (!mHandler.sendEmptyMessageAtTime(
+                MESSAGE_PROCESS_QUEUED_EVENTS, mEventQueueEnd.dispatchTime)) {
+            Slog.e(LOG_TAG, "Failed to schedule key event");
+        };
+    }
+
+    private void processQueuedEvents() {
+        final long currentTime = SystemClock.uptimeMillis();
+        while ((mEventQueueEnd != null) && (mEventQueueEnd.dispatchTime <= currentTime)) {
+            final long eventDelay = getEventDelay(mEventQueueEnd.event, mEventQueueEnd.policyFlags);
+            if (eventDelay > 0) {
+                // Reschedule the event
+                mEventQueueEnd.dispatchTime = currentTime + eventDelay;
+                return;
+            }
+            // We'll either send or drop the event
+            if (eventDelay == 0) {
+                mAms.notifyKeyEvent(mEventQueueEnd.event, mEventQueueEnd.policyFlags);
+            }
+            final KeyEventHolder eventToBeRecycled = mEventQueueEnd;
+            mEventQueueEnd = mEventQueueEnd.previous;
+            if (mEventQueueEnd != null) {
+                mEventQueueEnd.next = null;
+            }
+            eventToBeRecycled.recycle();
+            if (mEventQueueEnd == null) {
+                mEventQueueStart = null;
+            }
+        }
+    }
+
+    private long getEventDelay(KeyEvent event, int policyFlags) {
+        int keyCode = event.getKeyCode();
+        if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) || (keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
+            return mPolicy.interceptKeyBeforeDispatching(null, event, policyFlags);
+        }
+        return 0;
+    }
+
+    private static class KeyEventHolder {
+        private static final int MAX_POOL_SIZE = 32;
+        private static final Pools.SimplePool<KeyEventHolder> sPool =
+                new Pools.SimplePool<>(MAX_POOL_SIZE);
+
+        public int policyFlags;
+        public long dispatchTime;
+        public KeyEvent event;
+        public KeyEventHolder next;
+        public KeyEventHolder previous;
+
+        public static KeyEventHolder obtain(KeyEvent event, int policyFlags, long dispatchTime) {
+            KeyEventHolder holder = sPool.acquire();
+            if (holder == null) {
+                holder = new KeyEventHolder();
+            }
+            holder.event = KeyEvent.obtain(event);
+            holder.policyFlags = policyFlags;
+            holder.dispatchTime = dispatchTime;
+            return holder;
+        }
+
+        public void recycle() {
+            event.recycle();
+            event = null;
+            policyFlags = 0;
+            dispatchTime = 0;
+            next = null;
+            previous = null;
+            sPool.release(this);
+        }
+    }
 }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index aad4431..7ebda35 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -68,6 +68,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
@@ -2645,8 +2646,12 @@
             return;
         }
         synchronized (mLock) {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "appwidget ensure");
             ensureGroupStateLoadedLocked(userId);
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "appwidget reload");
             reloadWidgetsMaskedStateForGroup(mSecurityPolicy.getGroupParent(userId));
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
             final int N = mProviders.size();
             for (int i = 0; i < N; i++) {
@@ -2658,10 +2663,13 @@
                 }
 
                 if (provider.widgets.size() > 0) {
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                            "appwidget init " + provider.info.provider.getPackageName());
                     sendEnableIntentLocked(provider);
                     int[] appWidgetIds = getWidgetIds(provider.widgets);
                     sendUpdateIntentLocked(provider, appWidgetIds);
                     registerForBroadcastsLocked(provider, appWidgetIds);
+                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                 }
             }
         }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 25aa0d1..68b83e6 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -220,7 +220,12 @@
                     fillContextWithAllowedValuesLocked(mContexts.get(i), flags);
                 }
 
-                request = new FillRequest(requestId, mContexts, mClientState, flags);
+                // Dispatch a snapshot of the current contexts list since it may change
+                // until the dispatch happens. The items in the list don't need to be cloned
+                // since we don't hold on them anywhere else. The client state is not touched
+                // by us, so no need to copy.
+                request = new FillRequest(requestId, new ArrayList<>(mContexts),
+                        mClientState, flags);
             }
 
             mRemoteFillService.onFillRequest(request);
@@ -978,7 +983,11 @@
         // Remove pending fill requests as the session is finished.
         cancelCurrentRequestLocked();
 
-        final SaveRequest saveRequest = new SaveRequest(mContexts, mClientState);
+        // Dispatch a snapshot of the current contexts list since it may change
+        // until the dispatch happens. The items in the list don't need to be cloned
+        // since we don't hold on them anywhere else. The client state is not touched
+        // by us, so no need to copy.
+        final SaveRequest saveRequest = new SaveRequest(new ArrayList<>(mContexts), mClientState);
         mRemoteFillService.onSaveRequest(saveRequest);
     }
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 5c180f1..9486c15 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -98,6 +98,7 @@
 import android.os.SELinux;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.os.storage.IStorageManager;
@@ -397,9 +398,12 @@
         @Override
         public void onUnlockUser(int userId) {
             if (userId == UserHandle.USER_SYSTEM) {
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup init");
                 sInstance.initialize(userId);
+                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
                 // Migrate legacy setting
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup migrate");
                 if (!backupSettingMigrated(userId)) {
                     if (DEBUG) {
                         Slog.i(TAG, "Backup enable apparently not migrated");
@@ -420,12 +424,15 @@
                         }
                     }
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
                 try {
                     sInstance.setBackupEnabled(readBackupEnableState(userId));
                 } catch (RemoteException e) {
                     // can't happen; it's a local object
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             }
         }
     }
@@ -2819,11 +2826,11 @@
                         break;
 
                     case FINAL:
-                        if (!mFinished) finalizeBackup();
-                        else {
-                            Slog.e(TAG, "Duplicate finish");
+                        if (!mFinished) {
+                            finalizeBackup();
+                        } else {
+                            Slog.e(TAG, "Duplicate finish of K/V pass");
                         }
-                        mFinished = true;
                         break;
                 }
             }
@@ -3177,6 +3184,7 @@
                         break;
                 }
             }
+            mFinished = true;
             Slog.i(BackupManagerService.TAG, "K/V backup pass finished.");
             // Only once we're entirely finished do we release the wakelock for k/v backup.
             mWakelock.release();
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a15992d..e860dd6 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -2893,11 +2893,10 @@
     }
 
     final class UidObserver extends IUidObserver.Stub {
-        @Override public void onUidStateChanged(int uid, int procState,
-                long procStateSeq) throws RemoteException {
+        @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
         }
 
-        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
+        @Override public void onUidGone(int uid, boolean disabled) {
             if (disabled) {
                 synchronized (mLock) {
                     removeForStoppedLocked(uid);
@@ -2905,16 +2904,19 @@
             }
         }
 
-        @Override public void onUidActive(int uid) throws RemoteException {
+        @Override public void onUidActive(int uid) {
         }
 
-        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+        @Override public void onUidIdle(int uid, boolean disabled) {
             if (disabled) {
                 synchronized (mLock) {
                     removeForStoppedLocked(uid);
                 }
             }
         }
+
+        @Override public void onUidCachedChanged(int uid, boolean cached) {
+        }
     };
 
     private final BroadcastStats getStatsLocked(PendingIntent pi) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a2ba7af..a2e74b6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4949,7 +4949,7 @@
         if (!newNetwork.networkCapabilities.equalRequestableCapabilities(nc)) {
             Slog.wtf(TAG, String.format(
                     "BUG: %s changed requestable capabilities during rematch: %s -> %s",
-                    nc, newNetwork.networkCapabilities));
+                    newNetwork.name(), nc, newNetwork.networkCapabilities));
         }
         if (newNetwork.getCurrentScore() != score) {
             Slog.wtf(TAG, String.format(
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index ec275cc..b88bbc1 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -343,7 +343,7 @@
         public void setOwnedByTransform() {
             if (mOwnedByTransform) {
                 // Programming error
-                new IllegalStateException("Cannot own an SPI twice!");
+                throw new IllegalStateException("Cannot own an SPI twice!");
             }
 
             mOwnedByTransform = true;
@@ -605,38 +605,33 @@
             spis[direction] = mSpiRecords.get(c.getSpiResourceId(direction));
             int spi = spis[direction].getSpi();
             try {
-                int result =
-                        getNetdInstance()
-                                .ipSecAddSecurityAssociation(
-                                        resourceId,
-                                        c.getMode(),
-                                        direction,
-                                        (c.getLocalAddress() != null)
-                                                ? c.getLocalAddress().getHostAddress()
-                                                : "",
-                                        (c.getRemoteAddress() != null)
-                                                ? c.getRemoteAddress().getHostAddress()
-                                                : "",
-                                        (c.getNetwork() != null)
-                                                ? c.getNetwork().getNetworkHandle()
-                                                : 0,
-                                        spi,
-                                        (auth != null) ? auth.getName() : "",
-                                        (auth != null) ? auth.getKey() : null,
-                                        (auth != null) ? auth.getTruncationLengthBits() : 0,
-                                        (crypt != null) ? crypt.getName() : "",
-                                        (crypt != null) ? crypt.getKey() : null,
-                                        (crypt != null) ? crypt.getTruncationLengthBits() : 0,
-                                        encapType,
-                                        encapLocalPort,
-                                        encapRemotePort);
-                if (result != spi) {
-                    // TODO: cleanup the first SA if creation of second SA fails
-                    return new IpSecTransformResponse(
-                            IpSecManager.Status.SPI_UNAVAILABLE, INVALID_RESOURCE_ID);
-                }
+                getNetdInstance()
+                        .ipSecAddSecurityAssociation(
+                                resourceId,
+                                c.getMode(),
+                                direction,
+                                (c.getLocalAddress() != null)
+                                        ? c.getLocalAddress().getHostAddress()
+                                        : "",
+                                (c.getRemoteAddress() != null)
+                                        ? c.getRemoteAddress().getHostAddress()
+                                        : "",
+                                (c.getNetwork() != null)
+                                        ? c.getNetwork().getNetworkHandle()
+                                        : 0,
+                                spi,
+                                (auth != null) ? auth.getName() : "",
+                                (auth != null) ? auth.getKey() : null,
+                                (auth != null) ? auth.getTruncationLengthBits() : 0,
+                                (crypt != null) ? crypt.getName() : "",
+                                (crypt != null) ? crypt.getKey() : null,
+                                (crypt != null) ? crypt.getTruncationLengthBits() : 0,
+                                encapType,
+                                encapLocalPort,
+                                encapRemotePort);
             } catch (ServiceSpecificException e) {
                 // FIXME: get the error code and throw is at an IOException from Errno Exception
+                return new IpSecTransformResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
             }
         }
         // Both SAs were created successfully, time to construct a record and lock it away
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index 516f8f6..06c46b9 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -38,24 +38,11 @@
 
 public class MasterClearReceiver extends BroadcastReceiver {
     private static final String TAG = "MasterClear";
-    private static final String ACTION_WIPE_EUICC_DATA =
-            "com.android.internal.action.wipe_euicc_data";
-    private static final long DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS = 30000L; // 30 s
     private boolean mWipeExternalStorage;
     private boolean mWipeEsims;
-    private static CountDownLatch mEuiccFactoryResetLatch;
 
     @Override
     public void onReceive(final Context context, final Intent intent) {
-        if (ACTION_WIPE_EUICC_DATA.equals(intent.getAction())) {
-            if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
-                int detailedCode = intent.getIntExtra(
-                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
-                Slog.e(TAG, "Error wiping euicc data, Detailed code = " + detailedCode);
-            }
-            mEuiccFactoryResetLatch.countDown();
-            return;
-        }
         if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {
             if (!"google.com".equals(intent.getStringExtra("from"))) {
                 Slog.w(TAG, "Ignoring master clear request -- not from trusted server.");
@@ -84,7 +71,8 @@
             @Override
             public void run() {
                 try {
-                    RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe);
+                    RecoverySystem
+                            .rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims);
                     Log.wtf(TAG, "Still running after master clear?!");
                 } catch (IOException e) {
                     Slog.e(TAG, "Can't perform master clear/factory reset", e);
@@ -129,32 +117,6 @@
                         Context.STORAGE_SERVICE);
                 sm.wipeAdoptableDisks();
             }
-            if (mWipeEsims) {
-                EuiccManager euiccManager = (EuiccManager) mContext.getSystemService(
-                        Context.EUICC_SERVICE);
-                Intent intent = new Intent(mContext, MasterClearReceiver.class);
-                intent.setAction(ACTION_WIPE_EUICC_DATA);
-                PendingIntent callbackIntent = PendingIntent.getBroadcast(
-                        mContext,
-                        0 /* requestCode */,
-                        intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT);
-                mEuiccFactoryResetLatch = new CountDownLatch(1);
-                euiccManager.eraseSubscriptions(callbackIntent);
-                try {
-                    long waitingTime = Settings.Global.getLong(
-                            mContext.getContentResolver(),
-                            Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS,
-                            DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS);
-
-                    if (!mEuiccFactoryResetLatch.await(waitingTime, TimeUnit.MILLISECONDS)) {
-                        Slog.e(TAG, "Timeout wiping eUICC data.");
-                    }
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    Slog.e(TAG, "Wiping eUICC data interrupted", e);
-                }
-            }
             return null;
         }
 
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
new file mode 100644
index 0000000..e5fbdd21
--- /dev/null
+++ b/services/core/java/com/android/server/OWNERS
@@ -0,0 +1,9 @@
+per-file ConnectivityService.java=ek@google.com
+per-file ConnectivityService.java=hugobenichi@google.com
+per-file ConnectivityService.java=lorenzo@google.com
+per-file NetworkManagementService.java=ek@google.com
+per-file NetworkManagementService.java=hugobenichi@google.com
+per-file NetworkManagementService.java=lorenzo@google.com
+per-file NsdService.java=ek@google.com
+per-file NsdService.java=hugobenichi@google.com
+per-file NsdService.java=lorenzo@google.com
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 7a9bf21..298de80 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -85,6 +85,7 @@
     private final TextServicesSettings mSettings;
     @NonNull
     private final UserManager mUserManager;
+    private final Object mLock = new Object();
 
     public static final class Lifecycle extends SystemService {
         private TextServicesManagerService mService;
@@ -124,7 +125,7 @@
     }
 
     void systemRunning() {
-        synchronized (mSpellCheckerMap) {
+        synchronized (mLock) {
             if (!mSystemReady) {
                 mSystemReady = true;
                 resetInternalState(mSettings.getCurrentUserId());
@@ -133,13 +134,13 @@
     }
 
     void onSwitchUser(@UserIdInt int userId) {
-        synchronized (mSpellCheckerMap) {
+        synchronized (mLock) {
             resetInternalState(userId);
         }
     }
 
     void onUnlockUser(@UserIdInt int userId) {
-        synchronized(mSpellCheckerMap) {
+        synchronized (mLock) {
             final int currentUserId = mSettings.getCurrentUserId();
             if (userId != currentUserId) {
                 return;
@@ -215,7 +216,7 @@
             if (!isChangingPackagesOfCurrentUser()) {
                 return;
             }
-            synchronized (mSpellCheckerMap) {
+            synchronized (mLock) {
                 buildSpellCheckerMapLocked(
                         mContext, mSpellCheckerList, mSpellCheckerMap, mSettings);
                 // TODO: Update for each locale
@@ -440,7 +441,7 @@
     }
 
     private SpellCheckerInfo getCurrentSpellCheckerWithoutVerification() {
-        synchronized (mSpellCheckerMap) {
+        synchronized (mLock) {
             final String curSpellCheckerId = mSettings.getSelectedSpellChecker();
             if (DBG) {
                 Slog.w(TAG, "getCurrentSpellChecker: " + curSpellCheckerId);
@@ -464,7 +465,7 @@
         final int subtypeHashCode;
         final SpellCheckerInfo sci;
         final Locale systemLocale;
-        synchronized (mSpellCheckerMap) {
+        synchronized (mLock) {
             subtypeHashCode =
                     mSettings.getSelectedSpellCheckerSubtype(SpellCheckerSubtype.SUBTYPE_ID_NONE);
             if (DBG) {
@@ -546,7 +547,7 @@
             Slog.e(TAG, "getSpellCheckerService: Invalid input.");
             return;
         }
-        synchronized(mSpellCheckerMap) {
+        synchronized (mLock) {
             if (!mSpellCheckerMap.containsKey(sciId)) {
                 return;
             }
@@ -578,7 +579,7 @@
         if (!calledFromValidUser()) {
             return false;
         }
-        synchronized(mSpellCheckerMap) {
+        synchronized (mLock) {
             return isSpellCheckerEnabledLocked();
         }
     }
@@ -628,7 +629,7 @@
         if (DBG) {
             Slog.d(TAG, "FinishSpellCheckerService");
         }
-        synchronized(mSpellCheckerMap) {
+        synchronized (mLock) {
             final ArrayList<SpellCheckerBindGroup> removeList = new ArrayList<>();
             for (SpellCheckerBindGroup group : mSpellCheckerBindGroups.values()) {
                 if (group == null) continue;
@@ -698,7 +699,7 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        synchronized(mSpellCheckerMap) {
+        synchronized (mLock) {
             pw.println("Current Text Services Manager state:");
             pw.println("  Spell Checkers:");
             int spellCheckerIndex = 0;
@@ -796,7 +797,7 @@
                 Slog.d(TAG, "onServiceConnected");
             }
 
-            synchronized(mSpellCheckerMap) {
+            synchronized (mLock) {
                 mSpellChecker = spellChecker;
                 mConnected = true;
                 // Dispatch pending getISpellCheckerSession requests.
@@ -810,7 +811,7 @@
                 Slog.d(TAG, "onServiceDisconnected");
             }
 
-            synchronized(mSpellCheckerMap) {
+            synchronized (mLock) {
                 mSpellChecker = null;
                 mConnected = false;
             }
@@ -820,7 +821,7 @@
             if (DBG) {
                 Slog.w(TAG, "remove listener: " + listener.hashCode());
             }
-            synchronized(mSpellCheckerMap) {
+            synchronized (mLock) {
                 mListeners.unregister(listener);
                 cleanLocked();
             }
@@ -858,7 +859,7 @@
 
         public void removeAll() {
             Slog.e(TAG, "Remove the spell checker bind unexpectedly.");
-            synchronized(mSpellCheckerMap) {
+            synchronized (mLock) {
                 final int size = mListeners.getRegisteredCallbackCount();
                 for (int i = 0; i < size; ++i) {
                     mListeners.unregister(mListeners.getRegisteredCallbackItem(i));
@@ -898,7 +899,7 @@
 
         void onSessionCreated(@Nullable final ISpellCheckerSession newSession,
                 @NonNull final SessionRequest request) {
-            synchronized (mSpellCheckerMap) {
+            synchronized (mLock) {
                 if (mUnbindCalled) {
                     return;
                 }
@@ -926,7 +927,7 @@
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            synchronized(mSpellCheckerMap) {
+            synchronized (mLock) {
                 onServiceConnectedInnerLocked(name, service);
             }
         }
@@ -945,7 +946,7 @@
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            synchronized(mSpellCheckerMap) {
+            synchronized (mLock) {
                 onServiceDisconnectedInnerLocked(name);
             }
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 151a510..04df104 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -414,6 +414,7 @@
 import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.WindowManagerService;
 
+import java.text.SimpleDateFormat;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -4343,8 +4344,7 @@
         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
             for (int j = 0; j < N; ++j) {
                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
-                if (item.change == UidRecord.CHANGE_GONE
-                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
+                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
                     mValidateUids.remove(item.uid);
                 } else {
                     UidRecord validateUid = mValidateUids.get(item.uid);
@@ -4352,9 +4352,9 @@
                         validateUid = new UidRecord(item.uid);
                         mValidateUids.put(item.uid, validateUid);
                     }
-                    if (item.change == UidRecord.CHANGE_IDLE) {
+                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
                         validateUid.idle = true;
-                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
+                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
                         validateUid.idle = false;
                     }
                     validateUid.curProcState = validateUid.setProcState = item.processState;
@@ -4379,22 +4379,37 @@
             for (int j = 0; j < changesSize; j++) {
                 UidRecord.ChangeItem item = mActiveUidChanges[j];
                 final int change = item.change;
-                if (change == UidRecord.CHANGE_IDLE
-                        || change == UidRecord.CHANGE_GONE_IDLE) {
+                if (change == UidRecord.CHANGE_PROCSTATE &&
+                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
+                    // No-op common case: no significant change, the observer is not
+                    // interested in all proc state changes.
+                    continue;
+                }
+                if ((change & UidRecord.CHANGE_IDLE) != 0) {
                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                 "UID idle uid=" + item.uid);
                         observer.onUidIdle(item.uid, item.ephemeral);
                     }
-                } else if (change == UidRecord.CHANGE_ACTIVE) {
+                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                 "UID active uid=" + item.uid);
                         observer.onUidActive(item.uid);
                     }
                 }
-                if (change == UidRecord.CHANGE_GONE
-                        || change == UidRecord.CHANGE_GONE_IDLE) {
+                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
+                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
+                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                                "UID cached uid=" + item.uid);
+                        observer.onUidCachedChanged(item.uid, true);
+                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
+                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                                "UID active uid=" + item.uid);
+                        observer.onUidCachedChanged(item.uid, false);
+                    }
+                }
+                if ((change & UidRecord.CHANGE_GONE) != 0) {
                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                 "UID gone uid=" + item.uid);
@@ -5507,11 +5522,8 @@
             // NOTE: We should consider creating the file in native code atomically once we've
             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
             // can be removed.
-            try {
-                tracesFile = File.createTempFile("anr_", "", tracesDir);
-                FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
-            } catch (IOException ioe) {
-                Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
+            tracesFile = createAnrDumpFile(tracesDir);
+            if (tracesFile == null) {
                 return null;
             }
 
@@ -5523,6 +5535,31 @@
         return tracesFile;
     }
 
+    @GuardedBy("ActivityManagerService.class")
+    private static SimpleDateFormat sAnrFileDateFormat;
+
+    private static synchronized File createAnrDumpFile(File tracesDir) {
+        if (sAnrFileDateFormat == null) {
+            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
+        }
+
+        final String formattedDate = sAnrFileDateFormat.format(new Date());
+        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
+
+        try {
+            if (anrFile.createNewFile()) {
+                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
+                return anrFile;
+            } else {
+                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
+            }
+        } catch (IOException ioe) {
+            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
+        }
+
+        return null;
+    }
+
     /**
      * Prune all trace files that are more than a day old.
      *
@@ -17194,12 +17231,12 @@
                             }
                         } catch (IOException e) {
                             if (!isCheckinRequest) {
-                                pw.println("Got IoException!");
+                                pw.println("Got IoException! " + e);
                                 pw.flush();
                             }
                         } catch (RemoteException e) {
                             if (!isCheckinRequest) {
-                                pw.println("Got RemoteException!");
+                                pw.println("Got RemoteException! " + e);
                                 pw.flush();
                             }
                         }
@@ -21594,7 +21631,8 @@
                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
                                                 "Requesting dump heap from "
                                                 + myProc + " to " + heapdumpFile);
-                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
+                                        thread.dumpHeap(/* managed=*/ true, /* runGc= */ false,
+                                                heapdumpFile.toString(), fd);
                                     } catch (RemoteException e) {
                                     }
                                 }
@@ -22147,10 +22185,10 @@
             }
             if (uidRec != null) {
                 uidRec.pendingChange = pendingChange;
-                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
+                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
                     // If this uid is going away, and we haven't yet reported it is gone,
                     // then do so now.
-                    change = UidRecord.CHANGE_GONE_IDLE;
+                    change |= UidRecord.CHANGE_IDLE;
                 }
             } else if (uid < 0) {
                 throw new IllegalArgumentException("No UidRecord or uid");
@@ -22160,8 +22198,26 @@
             mPendingUidChanges.add(pendingChange);
         } else {
             pendingChange = uidRec.pendingChange;
-            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
-                change = UidRecord.CHANGE_GONE_IDLE;
+            // If there is no change in idle or active state, then keep whatever was pending.
+            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
+                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
+                        | UidRecord.CHANGE_ACTIVE));
+            }
+            // If there is no change in cached or uncached state, then keep whatever was pending.
+            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
+                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
+                        | UidRecord.CHANGE_UNCACHED));
+            }
+            // If this is a report of the UID being gone, then we shouldn't keep any previous
+            // report of it being active or cached.  (That is, a gone uid is never active,
+            // and never cached.)
+            if ((change & UidRecord.CHANGE_GONE) != 0) {
+                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
+                if (!uidRec.idle) {
+                    // If this uid is going away, and we haven't yet reported it is gone,
+                    // then do so now.
+                    change |= UidRecord.CHANGE_IDLE;
+                }
             }
         }
         pendingChange.change = change;
@@ -22170,27 +22226,26 @@
         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
         if (uidRec != null) {
+            uidRec.lastReportedChange = change;
             uidRec.updateLastDispatchedProcStateSeq(change);
         }
 
         // Directly update the power manager, since we sit on top of it and it is critical
         // it be kept in sync (so wake locks will be held as soon as appropriate).
         if (mLocalPowerManager != null) {
-            switch (change) {
-                case UidRecord.CHANGE_GONE:
-                case UidRecord.CHANGE_GONE_IDLE:
-                    mLocalPowerManager.uidGone(pendingChange.uid);
-                    break;
-                case UidRecord.CHANGE_IDLE:
-                    mLocalPowerManager.uidIdle(pendingChange.uid);
-                    break;
-                case UidRecord.CHANGE_ACTIVE:
-                    mLocalPowerManager.uidActive(pendingChange.uid);
-                    break;
-                default:
-                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
-                            pendingChange.processState);
-                    break;
+            // TO DO: dispatch cached/uncached changes here, so we don't need to report
+            // all proc state changes.
+            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
+                mLocalPowerManager.uidActive(pendingChange.uid);
+            }
+            if ((change & UidRecord.CHANGE_IDLE) != 0) {
+                mLocalPowerManager.uidIdle(pendingChange.uid);
+            }
+            if ((change & UidRecord.CHANGE_GONE) != 0) {
+                mLocalPowerManager.uidGone(pendingChange.uid);
+            } else {
+                mLocalPowerManager.updateUidProcState(pendingChange.uid,
+                        pendingChange.processState);
             }
         }
     }
@@ -22774,6 +22829,9 @@
                                     mConstants.BACKGROUND_SETTLE_TIME);
                         }
                     }
+                    if (!uidRec.setIdle) {
+                        uidChange = UidRecord.CHANGE_IDLE;
+                    }
                 } else {
                     if (uidRec.idle) {
                         uidChange = UidRecord.CHANGE_ACTIVE;
@@ -22782,8 +22840,17 @@
                     }
                     uidRec.lastBackgroundTime = 0;
                 }
+                final boolean wasCached = uidRec.setProcState
+                        > ActivityManager.PROCESS_STATE_RECEIVER && uidRec.setProcState
+                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
+                final boolean isCached = uidRec.curProcState
+                        > ActivityManager.PROCESS_STATE_RECEIVER;
+                if (wasCached != isCached) {
+                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
+                }
                 uidRec.setProcState = uidRec.curProcState;
                 uidRec.setWhitelist = uidRec.curWhitelist;
+                uidRec.setIdle = uidRec.idle;
                 enqueueUidChangeLocked(uidRec, -1, uidChange);
                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
                 if (uidRec.foregroundServices) {
@@ -22858,6 +22925,7 @@
                                     userId == UserHandle.getUserId(uidRec.uid)) {
                                 EventLogTags.writeAmUidIdle(uidRec.uid);
                                 uidRec.idle = true;
+                                uidRec.setIdle = true;
                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
                                         + " from package " + packageName + " user " + userId);
                                 doStopUidLocked(uidRec.uid, uidRec);
@@ -22893,6 +22961,7 @@
                     if (bgTime <= maxBgTime) {
                         EventLogTags.writeAmUidIdle(uidRec.uid);
                         uidRec.idle = true;
+                        uidRec.setIdle = true;
                         doStopUidLocked(uidRec.uid, uidRec);
                     } else {
                         if (nextTime == 0 || nextTime > bgTime) {
@@ -23325,7 +23394,7 @@
         return proc;
     }
 
-    public boolean dumpHeap(String process, int userId, boolean managed,
+    public boolean dumpHeap(String process, int userId, boolean managed, boolean runGc,
             String path, ParcelFileDescriptor fd) throws RemoteException {
 
         try {
@@ -23354,7 +23423,7 @@
                     }
                 }
 
-                proc.thread.dumpHeap(managed, path, fd);
+                proc.thread.dumpHeap(managed, runGc, path, fd);
                 fd = null;
                 return true;
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index f0a886d..5d24296 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -785,6 +785,7 @@
         final PrintWriter err = getErrPrintWriter();
         boolean managed = true;
         int userId = UserHandle.USER_CURRENT;
+        boolean runGc = false;
 
         String opt;
         while ((opt=getNextOption()) != null) {
@@ -796,6 +797,8 @@
                 }
             } else if (opt.equals("-n")) {
                 managed = false;
+            } else if (opt.equals("-g")) {
+                runGc = true;
             } else {
                 err.println("Error: Unknown option: " + opt);
                 return -1;
@@ -811,7 +814,7 @@
             return -1;
         }
 
-        if (!mInterface.dumpHeap(process, userId, managed, heapFile, fd)) {
+        if (!mInterface.dumpHeap(process, userId, managed, runGc, heapFile, fd)) {
             err.println("HEAP DUMP FAILED on process " + process);
             return -1;
         }
@@ -2555,10 +2558,11 @@
             pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
             pw.println("          between samples");
             pw.println("      --streaming: stream the profiling output to the specified file");
-            pw.println("  dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>");
+            pw.println("  dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
             pw.println("      Dump the heap of a process.  The given <PROCESS> argument may");
             pw.println("        be either a process name or pid.  Options are:");
             pw.println("      -n: dump native heap instead of managed heap");
+            pw.println("      -g: force GC before dumping the heap");
             pw.println("      --user <USER_ID> | current: When supplying a process name,");
             pw.println("          specify user of process to dump; uses current user if not specified.");
             pw.println("  set-debug-app [-w] [--persistent] <PACKAGE>");
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 4b2b6a7..4a57369 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -2168,7 +2168,7 @@
         if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
             if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
             mStartingWindowState = STARTING_WINDOW_REMOVED;
-            mWindowContainerController.removeStartingWindow();
+            mWindowContainerController.removeHiddenStartingWindow();
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 5b461a1..070e028 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1658,14 +1658,20 @@
         }
         final int stackBehindTopId = (stackBehindTopIndex >= 0)
                 ? mStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
-        if ((topStackId == DOCKED_STACK_ID || topStackId == PINNED_STACK_ID)
-                && (stackIndex == stackBehindTopIndex
-                || (stackBehindTopId == DOCKED_STACK_ID
-                && stackIndex == stackBehindTopIndex - 1))) {
-            // Stacks directly behind the docked or pinned stack are always visible.
-            // Also this stack is visible if behind docked stack and the docked stack is behind the
-            // top-most pinned stack
-            return STACK_VISIBLE;
+        if (topStackId == DOCKED_STACK_ID || StackId.isAlwaysOnTop(topStackId)) {
+            if (stackIndex == stackBehindTopIndex) {
+                // Stacks directly behind the docked or pinned stack are always visible.
+                return STACK_VISIBLE;
+            } else if (StackId.isAlwaysOnTop(topStackId) && stackIndex == stackBehindTopIndex - 1) {
+                // Otherwise, this stack can also be visible if it is directly behind a docked stack
+                // or translucent assistant stack behind an always-on-top top-most stack
+                if (stackBehindTopId == DOCKED_STACK_ID) {
+                    return STACK_VISIBLE;
+                } else if (stackBehindTopId == ASSISTANT_STACK_ID) {
+                    return mStacks.get(stackBehindTopIndex).isStackTranslucent(starting, mStackId)
+                            ? STACK_VISIBLE : STACK_INVISIBLE;
+                }
+            }
         }
 
         if (StackId.isBackdropToTranslucentActivity(topStackId)
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index c411bce..8efcb4f 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -39,6 +39,7 @@
     boolean curWhitelist;
     boolean setWhitelist;
     boolean idle;
+    boolean setIdle;
     int numProcs;
 
     /**
@@ -79,10 +80,11 @@
     final Object networkStateLock = new Object();
 
     static final int CHANGE_PROCSTATE = 0;
-    static final int CHANGE_GONE = 1;
-    static final int CHANGE_GONE_IDLE = 2;
-    static final int CHANGE_IDLE = 3;
-    static final int CHANGE_ACTIVE = 4;
+    static final int CHANGE_GONE = 1<<0;
+    static final int CHANGE_IDLE = 1<<1;
+    static final int CHANGE_ACTIVE = 1<<2;
+    static final int CHANGE_CACHED = 1<<3;
+    static final int CHANGE_UNCACHED = 1<<4;
 
     static final class ChangeItem {
         UidRecord uidRecord;
@@ -94,6 +96,7 @@
     }
 
     ChangeItem pendingChange;
+    int lastReportedChange;
 
     public UidRecord(int _uid) {
         uid = _uid;
@@ -112,12 +115,12 @@
     }
 
     /**
-     * If the change being dispatched is neither CHANGE_GONE nor CHANGE_GONE_IDLE (not interested in
+     * If the change being dispatched is not CHANGE_GONE (not interested in
      * these changes), then update the {@link #lastDispatchedProcStateSeq} with
      * {@link #curProcStateSeq}.
      */
     public void updateLastDispatchedProcStateSeq(int changeToDispatch) {
-        if (changeToDispatch != CHANGE_GONE && changeToDispatch != CHANGE_GONE_IDLE) {
+        if ((changeToDispatch & CHANGE_GONE) == 0) {
             lastDispatchedProcStateSeq = curProcStateSeq;
         }
     }
@@ -146,6 +149,41 @@
         if (idle) {
             sb.append(" idle");
         }
+        if (lastReportedChange != 0) {
+            sb.append(" change:");
+            boolean printed = false;
+            if ((lastReportedChange & CHANGE_GONE) != 0) {
+                printed = true;
+                sb.append("gone");
+            }
+            if ((lastReportedChange & CHANGE_IDLE) != 0) {
+                if (printed) {
+                    sb.append("|");
+                }
+                printed = true;
+                sb.append("idle");
+            }
+            if ((lastReportedChange & CHANGE_ACTIVE) != 0) {
+                if (printed) {
+                    sb.append("|");
+                }
+                printed = true;
+                sb.append("active");
+            }
+            if ((lastReportedChange & CHANGE_CACHED) != 0) {
+                if (printed) {
+                    sb.append("|");
+                }
+                printed = true;
+                sb.append("cached");
+            }
+            if ((lastReportedChange & CHANGE_UNCACHED) != 0) {
+                if (printed) {
+                    sb.append("|");
+                }
+                sb.append("uncached");
+            }
+        }
         sb.append(" procs:");
         sb.append(numProcs);
         sb.append(" seq(");
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index b89586d..2e27387 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -20,6 +20,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.app.IStopUserCallback;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -81,9 +82,18 @@
         if (newState == state) {
             return;
         }
-        Slog.i(TAG, "User " + mHandle.getIdentifier() + " state changed from "
+        final int userId = mHandle.getIdentifier();
+        if (state != STATE_BOOTING) {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    stateToString(state) + " " + userId, userId);
+        }
+        if (newState != STATE_SHUTDOWN) {
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    stateToString(newState) + " " + userId, userId);
+        }
+        Slog.i(TAG, "User " + userId + " state changed from "
                 + stateToString(state) + " to " + stateToString(newState));
-        EventLogTags.writeAmUserStateChanged(mHandle.getIdentifier(), newState);
+        EventLogTags.writeAmUserStateChanged(userId, newState);
         lastState = state;
         state = newState;
     }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 7eee3e4..834b964 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -28,6 +28,7 @@
 import android.app.ActivityManagerInternal;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
+import android.app.IUidObserver;
 import android.app.NotificationManager;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
@@ -624,6 +625,32 @@
         }
     }
 
+    final private IUidObserver mUidObserver = new IUidObserver.Stub() {
+        @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+        }
+
+        @Override public void onUidGone(int uid, boolean disabled) {
+            // Once the uid is no longer running, no need to keep trying to disable its audio.
+            disableAudioForUid(false, uid);
+        }
+
+        @Override public void onUidActive(int uid) throws RemoteException {
+        }
+
+        @Override public void onUidIdle(int uid, boolean disabled) {
+        }
+
+        @Override public void onUidCachedChanged(int uid, boolean cached) {
+            disableAudioForUid(cached, uid);
+        }
+
+        private void disableAudioForUid(boolean disable, int uid) {
+            queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
+                    disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
+                    null /* obj */,  0 /* delay */);
+        }
+    };
+
     ///////////////////////////////////////////////////////////////////////////
     // Construction
     ///////////////////////////////////////////////////////////////////////////
@@ -692,7 +719,6 @@
         // the mcc is read by onConfigureSafeVolume()
         mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_safe_media_volume_index) * 10;
-        mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
 
         mUseFixedVolume = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_useFixedVolume);
@@ -705,6 +731,10 @@
         mSettingsObserver = new SettingsObserver();
         createStreamStates();
 
+        // mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
+        // relies on audio policy having correct ranges for volume indexes.
+        mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
+
         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
 
         mRecordMonitor = new RecordingActivityMonitor(mContext);
@@ -757,6 +787,13 @@
     public void systemReady() {
         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
                 0, 0, null, 0);
+        try {
+            ActivityManager.getService().registerUidObserver(mUidObserver,
+                    ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
+                    ActivityManager.PROCESS_STATE_UNKNOWN, null);
+        } catch (RemoteException e) {
+            // ignored; both services live in system_server
+        }
     }
 
     public void onSystemReady() {
@@ -1908,6 +1945,7 @@
             streamType = getActiveStreamType(streamType);
         }
         synchronized (VolumeStreamState.class) {
+            ensureValidStreamType(streamType);
             return mStreamStates[streamType].mIsMuted;
         }
     }
@@ -3467,13 +3505,13 @@
             int index = (max + min) / 2;
             float gainDB = AudioSystem.getStreamVolumeDB(
                     AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET);
-            if (gainDB == Float.NaN) {
+            if (Float.isNaN(gainDB)) {
                 //keep last min in case of read error
                 break;
-            } else if (gainDB == SAVE_VOLUME_GAIN_DBFS) {
+            } else if (gainDB == SAFE_VOLUME_GAIN_DBFS) {
                 min = index;
                 break;
-            } else if (gainDB < SAVE_VOLUME_GAIN_DBFS) {
+            } else if (gainDB < SAFE_VOLUME_GAIN_DBFS) {
                 min = index;
             } else {
                 max = index;
@@ -5998,11 +6036,14 @@
     private int mMcc = 0;
     // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
     private int mSafeMediaVolumeIndex;
-    // mSafeUsbMediaVolumeIndex is used for USB Headsets and is to the music volume
-    // UI index corresponding to a gain of -15 dBFS. This corresponds to a loudness of 85 dB SPL
-    // if the headset is compliant to EN 60950 with a max loudness of 100dB SPL.
+    // mSafeUsbMediaVolumeIndex is used for USB Headsets and is the music volume UI index
+    // corresponding to a gain of -30 dBFS in audio flinger mixer.
+    // We remove -15 dBs from the theoretical -15dB to account for the EQ boost when bands are set
+    // to max gain.
+    // This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when
+    // the headset is compliant to EN 60950 with a max loudness of 100dB SPL.
     private int mSafeUsbMediaVolumeIndex;
-    private static final float SAVE_VOLUME_GAIN_DBFS = -15;
+    private static final float SAFE_VOLUME_GAIN_DBFS = -30.0f;
     // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
     private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |
                                                 AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
@@ -6602,13 +6643,6 @@
                 }
             }
         }
-
-        @Override
-        public void disableAudioForUid(boolean disable, int uid) {
-            queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
-                    disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
-                    null /* obj */,  0 /* delay */);
-        }
     }
 
     //==========================================================================================
diff --git a/services/core/java/com/android/server/connectivity/OWNERS b/services/core/java/com/android/server/connectivity/OWNERS
new file mode 100644
index 0000000..74f39a1
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/OWNERS
@@ -0,0 +1,5 @@
+set noparent
+
+ek@google.com
+hugobenichi@google.com
+lorenzo@google.com
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index b657335..1bee594 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1087,11 +1087,8 @@
         return list.toArray(new String[list.size()]);
     }
 
-    private void maybeLogMessage(State state, int what) {
-        if (DBG) {
-            Log.d(TAG, state.getName() + " got " +
-                    sMagicDecoderRing.get(what, Integer.toString(what)));
-        }
+    private void logMessage(State state, int what) {
+        mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
     }
 
     private boolean upstreamWanted() {
@@ -1215,7 +1212,7 @@
         class InitialState extends State {
             @Override
             public boolean processMessage(Message message) {
-                maybeLogMessage(this, message.what);
+                logMessage(this, message.what);
                 switch (message.what) {
                     case EVENT_IFACE_SERVING_STATE_ACTIVE:
                         TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
@@ -1307,21 +1304,21 @@
                 // Find the interface with the default IPv4 route. It may be the
                 // interface described by linkProperties, or one of the interfaces
                 // stacked on top of it.
-                Log.i(TAG, "Finding IPv4 upstream interface on: " + ns.linkProperties);
+                mLog.i("Finding IPv4 upstream interface on: " + ns.linkProperties);
                 RouteInfo ipv4Default = RouteInfo.selectBestRoute(
                     ns.linkProperties.getAllRoutes(), Inet4Address.ANY);
                 if (ipv4Default != null) {
                     iface = ipv4Default.getInterface();
-                    Log.i(TAG, "Found interface " + ipv4Default.getInterface());
+                    mLog.i("Found interface " + ipv4Default.getInterface());
                 } else {
-                    Log.i(TAG, "No IPv4 upstream interface, giving up.");
+                    mLog.i("No IPv4 upstream interface, giving up.");
                 }
             }
 
             if (iface != null) {
                 setDnsForwarders(ns.network, ns.linkProperties);
             }
-            notifyTetheredOfNewUpstreamIface(iface);
+            notifyDownstreamsOfNewUpstreamIface(iface);
             if (ns != null && pertainsToCurrentUpstream(ns)) {
                 // If we already have NetworkState for this network examine
                 // it immediately, because there likely will be no second
@@ -1356,8 +1353,8 @@
             }
         }
 
-        protected void notifyTetheredOfNewUpstreamIface(String ifaceName) {
-            if (DBG) Log.d(TAG, "Notifying tethered with upstream=" + ifaceName);
+        protected void notifyDownstreamsOfNewUpstreamIface(String ifaceName) {
+            mLog.log("Notifying downstreams of upstream=" + ifaceName);
             mCurrentUpstreamIface = ifaceName;
             for (TetherInterfaceStateMachine sm : mNotifyList) {
                 sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
@@ -1499,7 +1496,7 @@
                 mOffloadController.stop();
                 mUpstreamNetworkMonitor.stop();
                 mSimChange.stopListening();
-                notifyTetheredOfNewUpstreamIface(null);
+                notifyDownstreamsOfNewUpstreamIface(null);
                 handleNewUpstreamNetworkState(null);
             }
 
@@ -1518,7 +1515,7 @@
 
             @Override
             public boolean processMessage(Message message) {
-                maybeLogMessage(this, message.what);
+                logMessage(this, message.what);
                 boolean retValue = true;
                 switch (message.what) {
                     case EVENT_IFACE_SERVING_STATE_ACTIVE: {
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
index 20ec206..a69e4ca 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
@@ -142,8 +142,9 @@
     }
 
     private boolean isOffloadDisabled() {
-        // Defaults to |false| if not present.
-        return (Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0) != 0);
+        final int defaultDisposition = mHwInterface.getDefaultTetherOffloadDisabled();
+        return (Settings.Global.getInt(
+                mContentResolver, TETHER_OFFLOAD_DISABLED, defaultDisposition) != 0);
     }
 
     private boolean started() {
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
index 09fd96b..cd98b30 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
@@ -35,6 +35,10 @@
  */
 public class OffloadHardwareInterface {
     private static final String TAG = OffloadHardwareInterface.class.getSimpleName();
+    // Change this value to control whether tether offload is enabled or
+    // disabled by default in the absence of an explicit Settings value.
+    // See accompanying unittest to distinguish 0 from non-0 values.
+    private static final int DEFAULT_TETHER_OFFLOAD_DISABLED = 0;
     private static final String NO_INTERFACE_NAME = "";
     private static final String NO_IPV4_ADDRESS = "";
     private static final String NO_IPV4_GATEWAY = "";
@@ -60,6 +64,10 @@
         mLog = log.forSubComponent(TAG);
     }
 
+    public int getDefaultTetherOffloadDisabled() {
+        return DEFAULT_TETHER_OFFLOAD_DISABLED;
+    }
+
     public boolean initOffloadConfig() {
         return configOffload();
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 86b2551..4bac69c 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -441,12 +441,8 @@
         mLastRaParams = newParams;
     }
 
-    private void maybeLogMessage(State state, int what) {
-        if (DBG) {
-            Log.d(TAG, state.getName() + " got " +
-                    sMagicDecoderRing.get(what, Integer.toString(what)) + ", Iface = " +
-                    mIfaceName);
-        }
+    private void logMessage(State state, int what) {
+        mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
     }
 
     private void sendInterfaceState(int newInterfaceState) {
@@ -473,7 +469,7 @@
 
         @Override
         public boolean processMessage(Message message) {
-            maybeLogMessage(this, message.what);
+            logMessage(this, message.what);
             switch (message.what) {
                 case CMD_TETHER_REQUESTED:
                     mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
@@ -545,7 +541,7 @@
 
         @Override
         public boolean processMessage(Message message) {
-            maybeLogMessage(this, message.what);
+            logMessage(this, message.what);
             switch (message.what) {
                 case CMD_TETHER_UNREQUESTED:
                     transitionTo(mInitialState);
@@ -595,7 +591,7 @@
         public boolean processMessage(Message message) {
             if (super.processMessage(message)) return true;
 
-            maybeLogMessage(this, message.what);
+            logMessage(this, message.what);
             switch (message.what) {
                 case CMD_TETHER_REQUESTED:
                     mLog.e("CMD_TETHER_REQUESTED while in local-only hotspot mode.");
@@ -667,7 +663,7 @@
         public boolean processMessage(Message message) {
             if (super.processMessage(message)) return true;
 
-            maybeLogMessage(this, message.what);
+            logMessage(this, message.what);
             switch (message.what) {
                 case CMD_TETHER_REQUESTED:
                     mLog.e("CMD_TETHER_REQUESTED while already tethering.");
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 3fea51f..d99c27c 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -603,12 +603,11 @@
     }
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
-        @Override public void onUidStateChanged(int uid, int procState,
-                long procStateSeq) throws RemoteException {
+        @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
             updateUidState(uid, procState);
         }
 
-        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
+        @Override public void onUidGone(int uid, boolean disabled) {
             updateUidState(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
             if (disabled) {
                 cancelJobsForUid(uid, "uid gone");
@@ -618,11 +617,14 @@
         @Override public void onUidActive(int uid) throws RemoteException {
         }
 
-        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+        @Override public void onUidIdle(int uid, boolean disabled) {
             if (disabled) {
                 cancelJobsForUid(uid, "app uid idle");
             }
         }
+
+        @Override public void onUidCachedChanged(int uid, boolean cached) {
+        }
     };
 
     public Object getLock() {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index c1e820c..8d53447 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1931,7 +1931,8 @@
      *     This is the untrusted credential reset, OR the user sets a new lockscreen password
      *     FOR THE FIRST TIME on a SP-enabled device. New credential and new SID will be created
      */
-    private AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
+    @VisibleForTesting
+    protected AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
             String credential, int credentialType, int requestedQuality,
             int userId) throws RemoteException {
         Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
@@ -1982,7 +1983,8 @@
       return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
     }
 
-    private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
+    @VisibleForTesting
+    protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
         long handle = getSyntheticPasswordHandleLocked(userId);
         // This is a global setting
         long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
@@ -2017,6 +2019,10 @@
             authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
                     getGateKeeperService(), handle, userCredential, userId);
 
+            if (authResult.credentialType != credentialType) {
+                Slog.e(TAG, "Credential type mismatch.");
+                return VerifyCredentialResponse.ERROR;
+            }
             response = authResult.gkResponse;
             // credential has matched
             if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
@@ -2136,6 +2142,14 @@
                 getGateKeeperService(), handle, savedCredential, userId);
         VerifyCredentialResponse response = authResult.gkResponse;
         AuthenticationToken auth = authResult.authToken;
+
+        // If existing credential is provided, then it must match.
+        if (savedCredential != null && auth == null) {
+            throw new RemoteException("Failed to enroll " +
+                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
+                            : "pattern"));
+        }
+
         if (auth != null) {
             // We are performing a trusted credential change i.e. a correct existing credential
             // is provided
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index f45c208..603e46a 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -127,6 +127,7 @@
     static class AuthenticationResult {
         public AuthenticationToken authToken;
         public VerifyCredentialResponse gkResponse;
+        public int credentialType;
     }
 
     static class AuthenticationToken {
@@ -754,6 +755,8 @@
      * Decrypt a synthetic password by supplying the user credential and corresponding password
      * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
      * verification to referesh the SID & Auth token maintained by the system.
+     * Note: the credential type is not validated here since there are call sites where the type is
+     * unknown. Caller might choose to validate it by examining AuthenticationResult.credentialType
      */
     public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
             long handle, String credential, int userId) throws RemoteException {
@@ -762,6 +765,7 @@
         }
         AuthenticationResult result = new AuthenticationResult();
         PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
+        result.credentialType = pwd.passwordType;
         byte[] pwdToken = computePasswordToken(credential, pwd);
 
         final byte[] applicationId;
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index a0487f9..b77ed91 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -108,6 +108,7 @@
     private ContentResolver mContentResolver;
     private SettingsObserver mSettingsObserver;
     private INotificationManager mNotificationManager;
+    private boolean mHasFeatureLeanback;
 
     // The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile)
     // It's always not null after the MediaSessionService is started.
@@ -154,6 +155,8 @@
         mContentResolver = getContext().getContentResolver();
         mSettingsObserver = new SettingsObserver();
         mSettingsObserver.observe();
+        mHasFeatureLeanback = getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_LEANBACK);
 
         updateUser();
     }
@@ -1509,7 +1512,7 @@
 
         private boolean isVoiceKey(int keyCode) {
             return keyCode == KeyEvent.KEYCODE_HEADSETHOOK
-                    || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
+                    || (!mHasFeatureLeanback && keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
         }
 
         private boolean isUserSetupComplete() {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0f1cfa5..b6af076 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -800,20 +800,22 @@
     }
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
-        @Override public void onUidStateChanged(int uid, int procState,
-                long procStateSeq) throws RemoteException {
+        @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
             mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
                     uid, procState, procStateSeq).sendToTarget();
         }
 
-        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
+        @Override public void onUidGone(int uid, boolean disabled) {
             mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
         }
 
-        @Override public void onUidActive(int uid) throws RemoteException {
+        @Override public void onUidActive(int uid) {
         }
 
-        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+        @Override public void onUidIdle(int uid, boolean disabled) {
+        }
+
+        @Override public void onUidCachedChanged(int uid, boolean cached) {
         }
     };
 
diff --git a/services/core/java/com/android/server/notification/AlertRateLimiter.java b/services/core/java/com/android/server/notification/AlertRateLimiter.java
index e4a7934..2b01945 100644
--- a/services/core/java/com/android/server/notification/AlertRateLimiter.java
+++ b/services/core/java/com/android/server/notification/AlertRateLimiter.java
@@ -24,7 +24,7 @@
     static final long ALLOWED_ALERT_INTERVAL = 1000;
     private long mLastNotificationMillis = 0;
 
-    boolean isRateLimited(long now) {
+   boolean shouldRateLimitAlert(long now) {
         final long millisSinceLast = now - mLastNotificationMillis;
         if (millisSinceLast < 0 || millisSinceLast < ALLOWED_ALERT_INTERVAL) {
             return true;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 48b4c57..c57b2fe 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -20,6 +20,7 @@
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.service.notification.NotificationListenerService
         .NOTIFICATION_CHANNEL_OR_GROUP_ADDED;
 import static android.service.notification.NotificationListenerService
@@ -210,7 +211,7 @@
             = SystemProperties.getBoolean("debug.child_notifs", true);
 
     static final int MAX_PACKAGE_NOTIFICATIONS = 50;
-    static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 10f;
+    static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
 
     // message codes
     static final int MESSAGE_TIMEOUT = 2;
@@ -573,7 +574,8 @@
         }
     }
 
-    private final NotificationDelegate mNotificationDelegate = new NotificationDelegate() {
+    @VisibleForTesting
+    final NotificationDelegate mNotificationDelegate = new NotificationDelegate() {
 
         @Override
         public void onSetDisabled(int status) {
@@ -3358,6 +3360,15 @@
                     pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                     (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
             Notification.addFieldsFromContext(ai, notification);
+
+            int canColorize = mPackageManagerClient.checkPermission(
+                    android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg);
+            if (canColorize == PERMISSION_GRANTED) {
+                notification.flags |= Notification.FLAG_CAN_COLORIZE;
+            } else {
+                notification.flags &= ~Notification.FLAG_CAN_COLORIZE;
+            }
+
         } catch (NameNotFoundException e) {
             Slog.e(TAG, "Cannot create a context for sending app", e);
             return;
@@ -3461,8 +3472,19 @@
         // package or a registered listener can enqueue.  Prevents DOS attacks and deals with leaks.
         if (!isSystemNotification && !isNotificationFromListener) {
             synchronized (mNotificationLock) {
-                if (mNotificationsByKey.get(r.sbn.getKey()) != null) {
-                    // this is an update, rate limit updates only
+                if (mNotificationsByKey.get(r.sbn.getKey()) == null && isCallerInstantApp(pkg)) {
+                    // Ephemeral apps have some special constraints for notifications.
+                    // They are not allowed to create new notifications however they are allowed to
+                    // update notifications created by the system (e.g. a foreground service
+                    // notification).
+                    throw new SecurityException("Instant app " + pkg
+                            + " cannot create notifications");
+                }
+
+                // rate limit updates that aren't completed progress notifications
+                if (mNotificationsByKey.get(r.sbn.getKey()) != null
+                        && !r.getNotification().hasCompletedProgress()) {
+
                     final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
                     if (appEnqueueRate > mMaxPackageEnqueueRate) {
                         mUsageStats.registerOverRateQuota(pkg);
@@ -3474,33 +3496,15 @@
                         }
                         return false;
                     }
-                } else if (isCallerInstantApp(pkg)) {
-                    // Ephemeral apps have some special constraints for notifications.
-                    // They are not allowed to create new notifications however they are allowed to
-                    // update notifications created by the system (e.g. a foreground service
-                    // notification).
-                    throw new SecurityException("Instant app " + pkg
-                            + " cannot create notifications");
                 }
 
-                int count = 0;
-                final int N = mNotificationList.size();
-                for (int i=0; i<N; i++) {
-                    final NotificationRecord existing = mNotificationList.get(i);
-                    if (existing.sbn.getPackageName().equals(pkg)
-                            && existing.sbn.getUserId() == userId) {
-                        if (existing.sbn.getId() == id
-                                && TextUtils.equals(existing.sbn.getTag(), tag)) {
-                            break;  // Allow updating existing notification
-                        }
-                        count++;
-                        if (count >= MAX_PACKAGE_NOTIFICATIONS) {
-                            mUsageStats.registerOverCountQuota(pkg);
-                            Slog.e(TAG, "Package has already posted " + count
-                                    + " notifications.  Not showing more.  package=" + pkg);
-                            return false;
-                        }
-                    }
+                // limit the number of outstanding notificationrecords an app can have
+                int count = getNotificationCountLocked(pkg, userId, id, tag);
+                if (count >= MAX_PACKAGE_NOTIFICATIONS) {
+                    mUsageStats.registerOverCountQuota(pkg);
+                    Slog.e(TAG, "Package has already posted or enqueued " + count
+                            + " notifications.  Not showing more.  package=" + pkg);
+                    return false;
                 }
             }
         }
@@ -3527,6 +3531,32 @@
         return true;
     }
 
+    protected int getNotificationCountLocked(String pkg, int userId, int excludedId,
+            String excludedTag) {
+        int count = 0;
+        final int N = mNotificationList.size();
+        for (int i = 0; i < N; i++) {
+            final NotificationRecord existing = mNotificationList.get(i);
+            if (existing.sbn.getPackageName().equals(pkg)
+                    && existing.sbn.getUserId() == userId) {
+                if (existing.sbn.getId() == excludedId
+                        && TextUtils.equals(existing.sbn.getTag(), excludedTag)) {
+                    continue;
+                }
+                count++;
+            }
+        }
+        final int M = mEnqueuedNotifications.size();
+        for (int i = 0; i < M; i++) {
+            final NotificationRecord existing = mEnqueuedNotifications.get(i);
+            if (existing.sbn.getPackageName().equals(pkg)
+                    && existing.sbn.getUserId() == userId) {
+                count++;
+            }
+        }
+        return count;
+    }
+
     protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
         final String pkg = r.sbn.getPackageName();
         final int callingUid = r.sbn.getUid();
@@ -3830,7 +3860,8 @@
         // notification was a summary and the new one isn't, or when the old
         // notification was a summary and its group key changed.
         if (oldIsSummary && (!isSummary || !oldGroup.equals(group))) {
-            cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */);
+            cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */,
+                    null);
         }
     }
 
@@ -4581,7 +4612,7 @@
                         boolean wasPosted = removeFromNotificationListsLocked(r);
                         cancelNotificationLocked(r, sendDelete, reason, wasPosted);
                         cancelGroupChildrenLocked(r, callingUid, callingPid, listenerName,
-                                sendDelete);
+                                sendDelete, null);
                         updateLightsLocked();
                     } else {
                         // No notification was found, assume that it is snoozed and cancel it.
@@ -4652,7 +4683,6 @@
                         }
                         return true;
                     };
-
                     cancelAllNotificationsByListLocked(mNotificationList, callingUid, callingPid,
                             pkg, true /*nullPkgIndicatesUserSwitch*/, channelId, flagChecker,
                             false /*includeCurrentProfiles*/, userId, false /*sendDelete*/, reason,
@@ -4700,7 +4730,6 @@
             if (channelId != null && !channelId.equals(r.getChannel().getId())) {
                 continue;
             }
-
             if (canceledNotifications == null) {
                 canceledNotifications = new ArrayList<>();
             }
@@ -4712,7 +4741,7 @@
             final int M = canceledNotifications.size();
             for (int i = 0; i < M; i++) {
                 cancelGroupChildrenLocked(canceledNotifications.get(i), callingUid, callingPid,
-                        listenerName, false /* sendDelete */);
+                        listenerName, false /* sendDelete */, flagChecker);
             }
             updateLightsLocked();
         }
@@ -4779,7 +4808,7 @@
     // Warning: The caller is responsible for invoking updateLightsLocked().
     @GuardedBy("mNotificationLock")
     private void cancelGroupChildrenLocked(NotificationRecord r, int callingUid, int callingPid,
-            String listenerName, boolean sendDelete) {
+            String listenerName, boolean sendDelete, FlagChecker flagChecker) {
         Notification n = r.getNotification();
         if (!n.isGroupSummary()) {
             return;
@@ -4793,15 +4822,15 @@
         }
 
         cancelGroupChildrenByListLocked(mNotificationList, r, callingUid, callingPid, listenerName,
-                sendDelete, true);
+                sendDelete, true, flagChecker);
         cancelGroupChildrenByListLocked(mEnqueuedNotifications, r, callingUid, callingPid,
-                listenerName, sendDelete, false);
+                listenerName, sendDelete, false, flagChecker);
     }
 
     @GuardedBy("mNotificationLock")
     private void cancelGroupChildrenByListLocked(ArrayList<NotificationRecord> notificationList,
             NotificationRecord parentNotification, int callingUid, int callingPid,
-            String listenerName, boolean sendDelete, boolean wasPosted) {
+            String listenerName, boolean sendDelete, boolean wasPosted, FlagChecker flagChecker) {
         final String pkg = parentNotification.sbn.getPackageName();
         final int userId = parentNotification.getUserId();
         final int reason = REASON_GROUP_SUMMARY_CANCELED;
@@ -4810,7 +4839,8 @@
             final StatusBarNotification childSbn = childR.sbn;
             if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) &&
                     childR.getGroupKey().equals(parentNotification.getGroupKey())
-                    && (childR.getFlags() & Notification.FLAG_FOREGROUND_SERVICE) == 0) {
+                    && (childR.getFlags() & Notification.FLAG_FOREGROUND_SERVICE) == 0
+                    && (flagChecker == null || flagChecker.apply(childR.getFlags()))) {
                 EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
                         childSbn.getTag(), userId, 0, 0, reason, listenerName);
                 notificationList.remove(i);
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 6953ffd..1dee71c 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -386,6 +386,7 @@
         prefix = prefix + "  ";
         pw.println(prefix + "uid=" + sbn.getUid() + " userId=" + sbn.getUserId());
         pw.println(prefix + "icon=" + iconStr);
+        pw.println(prefix + "flags=0x" + Integer.toHexString(notification.flags));
         pw.println(prefix + "pri=" + notification.priority);
         pw.println(prefix + "key=" + sbn.getKey());
         pw.println(prefix + "seen=" + mIsSeen);
@@ -495,6 +496,7 @@
         pw.println(prefix + "mAttributes= " + mAttributes);
         pw.println(prefix + "mLight= " + mLight);
         pw.println(prefix + "mShowBadge=" + mShowBadge);
+        pw.println(prefix + "mColorized=" + notification.isColorized());
         pw.println(prefix + "effectiveNotificationChannel=" + getChannel());
         if (getPeopleOverride() != null) {
             pw.println(prefix + "overridePeople= " + TextUtils.join(",", getPeopleOverride()));
@@ -530,10 +532,10 @@
     public final String toString() {
         return String.format(
                 "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s importance=%d key=%s" +
-                        " channel=%s: %s)",
+                        ": %s)",
                 System.identityHashCode(this),
                 this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(),
-                this.sbn.getTag(), this.mImportance, this.sbn.getKey(), this.getChannel().getId(),
+                this.sbn.getTag(), this.mImportance, this.sbn.getKey(),
                 this.sbn.getNotification());
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 3689cb1..c8f4d31 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -40,6 +40,7 @@
 import org.json.JSONObject;
 
 import java.io.PrintWriter;
+import java.lang.Math;
 import java.util.ArrayDeque;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
@@ -594,7 +595,7 @@
         }
 
         public boolean isAlertRateLimited() {
-            boolean limited = alertRate.isRateLimited(SystemClock.elapsedRealtime());
+            boolean limited = alertRate.shouldRateLimitAlert(SystemClock.elapsedRealtime());
             if (limited) {
                 numAlertViolations++;
             }
@@ -748,8 +749,8 @@
         }
 
         void increment(int imp) {
-            imp = imp < 0 ? 0 : imp > NUM_IMPORTANCES ? NUM_IMPORTANCES : imp;
-            mCount[imp] ++;
+            imp = Math.max(0, Math.min(imp, mCount.length - 1));
+            mCount[imp]++;
         }
 
         void maybeCount(ImportanceHistogram prev) {
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 5c4c040..bd765b4 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -258,7 +258,7 @@
 
     public long[] getExternalSize(String uuid, int userId, int flags, int[] appIds)
             throws InstallerException {
-        if (!checkBeforeRemote()) return new long[4];
+        if (!checkBeforeRemote()) return new long[6];
         try {
             return mInstalld.getExternalSize(uuid, userId, flags, appIds);
         } catch (Exception e) {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 54ca6b9..2a45d15 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -345,6 +345,10 @@
                 mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName),
                 true /* bootComplete */);
 
+        mPackageManagerService.getDexManager().dexoptSecondaryDex(pkg.packageName,
+                getCompilerFilterForReason(compilationReason),
+                false /* force */,
+                false /* compileOnlySharedDex */);
         return commands;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 5c54ba8..5823771 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -927,7 +927,7 @@
         // This is kind of hacky; we're creating a half-parsed package that is
         // straddled between the inherited and staged APKs.
         final PackageLite pkg = new PackageLite(null, baseApk, null, null, null, null,
-                splitPaths.toArray(new String[splitPaths.size()]), null);
+                splitPaths.toArray(new String[splitPaths.size()]), null, null);
         final boolean isForwardLocked =
                 (params.installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 92c5862..700d3c2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9340,12 +9340,23 @@
             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
             // trade-off worth doing to save boot time work.
-            int dexOptStatus = performDexOptTraced(pkg.packageName,
+            int primaryDexOptStaus = performDexOptTraced(pkg.packageName,
                     false /* checkProfiles */,
                     compilerFilter,
                     false /* force */,
                     bootComplete);
-            switch (dexOptStatus) {
+
+            if (pkg.isSystemApp()) {
+                // Only dexopt shared secondary dex files belonging to system apps to not slow down
+                // too much boot after an OTA.
+                mDexManager.dexoptSecondaryDex(pkg.packageName,
+                        compilerFilter,
+                        false /* force */,
+                        true /* compileOnlySharedDex */);
+            }
+
+            // TODO(shubhamajmera): Record secondary dexopt stats.
+            switch (primaryDexOptStaus) {
                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
                     numberOfPackagesOptimized++;
                     break;
@@ -9356,7 +9367,7 @@
                     numberOfPackagesFailed++;
                     break;
                 default:
-                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
+                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
                     break;
             }
         }
@@ -9559,8 +9570,8 @@
         } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
             return false;
         }
-        mDexManager.reconcileSecondaryDexFiles(packageName);
-        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
+        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force,
+                /* compileOnlySharedDex*/ false);
     }
 
     public boolean performDexOptSecondary(String packageName, int compileReason,
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 20d7b28..9765113 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -175,7 +175,7 @@
                 try {
                     ApkLite baseApk = PackageParser.parseApkLite(file, 0);
                     PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
-                            null, null);
+                            null, null, null);
                     params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
                             pkgLite, false, params.sessionParams.abiOverride));
                 } catch (PackageParserException | IOException e) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 7911972..0e572d8 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -483,22 +483,24 @@
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
         @Override
-        public void onUidStateChanged(int uid, int procState, long procStateSeq)
-                throws RemoteException {
+        public void onUidStateChanged(int uid, int procState, long procStateSeq) {
             handleOnUidStateChanged(uid, procState);
         }
 
         @Override
-        public void onUidGone(int uid, boolean disabled) throws RemoteException {
+        public void onUidGone(int uid, boolean disabled) {
             handleOnUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
         }
 
         @Override
-        public void onUidActive(int uid) throws RemoteException {
+        public void onUidActive(int uid) {
         }
 
         @Override
-        public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+        public void onUidIdle(int uid, boolean disabled) {
+        }
+
+        @Override public void onUidCachedChanged(int uid, boolean cached) {
         }
     };
 
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index be50eee..db2d30f 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -307,7 +307,7 @@
     public boolean dexoptSecondaryDex(String packageName, int compilerReason, boolean force) {
         return dexoptSecondaryDex(packageName,
                 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(compilerReason),
-                force);
+                force, /* compileOnlySharedDex */ false);
     }
 
     /**
@@ -315,7 +315,8 @@
      * @return true if all secondary dex files were processed successfully (compiled or skipped
      *         because they don't need to be compiled)..
      */
-    public boolean dexoptSecondaryDex(String packageName, String compilerFilter, boolean force) {
+    public boolean dexoptSecondaryDex(String packageName, String compilerFilter, boolean force,
+            boolean compileOnlySharedDex) {
         // Select the dex optimizer based on the force parameter.
         // Forced compilation is done through ForcedUpdatePackageDexOptimizer which will adjust
         // the necessary dexopt flags to make sure that compilation is not skipped. This avoid
@@ -337,6 +338,9 @@
         for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
             String dexPath = entry.getKey();
             DexUseInfo dexUseInfo = entry.getValue();
+            if (compileOnlySharedDex && !dexUseInfo.isUsedByOtherApps()) {
+                continue;
+            }
             PackageInfo pkg = null;
             try {
                 pkg = mPackageManager.getPackageInfo(packageName, /*flags*/0,
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5d2d4b6..8425d23 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -563,7 +563,7 @@
     int mPanicPressOnBackBehavior;
     int mShortPressOnSleepBehavior;
     int mShortPressWindowBehavior;
-    boolean mAwake;
+    volatile boolean mAwake;
     boolean mScreenOnEarly;
     boolean mScreenOnFully;
     ScreenOnListener mScreenOnListener;
@@ -6813,6 +6813,11 @@
         }
     }
 
+    @Override
+    public boolean isInteractive() {
+        return mAwake;
+    }
+
     /** {@inheritDoc} */
     @Override
     public void enableKeyguard(boolean enabled) {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a94484a..c688542 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2949,8 +2949,15 @@
             boolean disabled = false;
             final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);
             if (appid >= Process.FIRST_APPLICATION_UID) {
+                // Cached inactive processes are never allowed to hold wake locks.
+                if (mConstants.NO_CACHED_WAKE_LOCKS) {
+                    disabled = !wakeLock.mUidState.mActive &&
+                            wakeLock.mUidState.mProcState
+                                    != ActivityManager.PROCESS_STATE_NONEXISTENT &&
+                            wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER;
+                }
                 if (mDeviceIdleMode) {
-                    // If we are in idle mode, we will ignore all partial wake locks that are
+                    // If we are in idle mode, we will also ignore all partial wake locks that are
                     // for application uids that are not whitelisted.
                     final UidState state = wakeLock.mUidState;
                     if (Arrays.binarySearch(mDeviceIdleWhitelist, appid) < 0 &&
@@ -2959,11 +2966,6 @@
                             state.mProcState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
                         disabled = true;
                     }
-                } else if (mConstants.NO_CACHED_WAKE_LOCKS) {
-                    disabled = !wakeLock.mUidState.mActive &&
-                            wakeLock.mUidState.mProcState
-                                    != ActivityManager.PROCESS_STATE_NONEXISTENT &&
-                            wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER;
                 }
             }
             if (wakeLock.mDisabled != disabled) {
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index 3d60dcf6..d97ba2d 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -424,8 +424,7 @@
                             if (stagedDistroRulesVersion == null) {
                                 pw.println("<None>");
                             } else {
-                                pw.println("Staged install version: "
-                                        + stagedDistroRulesVersion.toDumpString());
+                                pw.println(stagedDistroRulesVersion.toDumpString());
                             }
                             break;
                         case 'a':
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index c07bd8e..a7cd962 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -67,7 +67,6 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -589,22 +588,20 @@
     }
 
     private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
+        if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
+            return;
+        }
+        PackageManager pm = mContext.getPackageManager();
+        List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
         ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
         boolean shouldUseDefaultAgent = defaultAgent != null;
+        ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
 
         if (shouldUseDefaultAgent) {
+            discoveredAgents.add(defaultAgent);
             Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
-            utils.setEnabledTrustAgents(Collections.singleton(defaultAgent), userId);
         } else { // A default agent is not set; perform regular trust agent discovery
-            if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
-                return;
-            }
-            PackageManager pm = mContext.getPackageManager();
-            List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
-
-            ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
-
             for (ResolveInfo resolveInfo : resolveInfos) {
                 ComponentName componentName = getComponentName(resolveInfo);
                 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
@@ -615,13 +612,13 @@
                 }
                 discoveredAgents.add(componentName);
             }
-
-            List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
-            if (previouslyEnabledAgents != null) {
-                discoveredAgents.addAll(previouslyEnabledAgents);
-            }
-            utils.setEnabledTrustAgents(discoveredAgents, userId);
         }
+
+        List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
+        if (previouslyEnabledAgents != null) {
+            discoveredAgents.addAll(previouslyEnabledAgents);
+        }
+        utils.setEnabledTrustAgents(discoveredAgents, userId);
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
     }
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index b1c1df1..69d8ca6 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -59,7 +59,7 @@
     /**
      * The default height of the VR virtual display
      */
-    public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1400;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1800;
 
     /**
      * The default height of the VR virtual dpi.
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 917f0b9..802054e 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -32,6 +32,7 @@
 import android.app.IWallpaperManagerCallback;
 import android.app.PendingIntent;
 import android.app.UserSwitchObserver;
+import android.app.WallpaperColors;
 import android.app.WallpaperInfo;
 import android.app.WallpaperManager;
 import android.app.admin.DevicePolicyManager;
@@ -55,7 +56,6 @@
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -64,8 +64,8 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
-import android.os.Process;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SELinux;
@@ -76,12 +76,10 @@
 import android.service.wallpaper.IWallpaperConnection;
 import android.service.wallpaper.IWallpaperEngine;
 import android.service.wallpaper.IWallpaperService;
-import android.app.WallpaperColors;
 import android.service.wallpaper.WallpaperService;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.EventLog;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -99,7 +97,6 @@
 import com.android.server.FgThread;
 import com.android.server.SystemService;
 
-import java.util.ArrayList;
 import libcore.io.IoUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -347,32 +344,44 @@
             needsExtraction = wallpaper.primaryColors == null;
         }
 
-        // This should not be synchronized because color extraction
-        // might take a while.
+        // Let's notify the current values, it's fine if it's null, it just means
+        // that we don't know yet.
+        notifyColorListeners(wallpaper.primaryColors, which);
+
         if (needsExtraction) {
             extractColors(wallpaper);
+            notifyColorListeners(wallpaper.primaryColors, which);
         }
+    }
 
+    private void notifyColorListeners(WallpaperColors wallpaperColors, int which) {
+        final IWallpaperManagerCallback[] listeners;
+        final IWallpaperManagerCallback keyguardListener;
         synchronized (mLock) {
-            final int n = mColorsChangedListeners.beginBroadcast();
-            for (int i = 0; i < n; i++) {
-                IWallpaperManagerCallback callback = mColorsChangedListeners.getBroadcastItem(i);
-                try {
-                    callback.onWallpaperColorsChanged(wallpaper.primaryColors, which);
-                } catch (RemoteException e) {
-                    // Callback is gone, it's not necessary to unregister it since
-                    // RemoteCallbackList#getBroadcastItem will take care of it.
-                }
+            // Make a synchronized copy of the listeners to avoid concurrent list modification.
+            int callbackCount = mColorsChangedListeners.beginBroadcast();
+            listeners = new IWallpaperManagerCallback[callbackCount];
+            for (int i = 0; i < callbackCount; i++) {
+                listeners[i] = mColorsChangedListeners.getBroadcastItem(i);
             }
             mColorsChangedListeners.finishBroadcast();
+            keyguardListener = mKeyguardListener;
+        }
 
-            final IWallpaperManagerCallback cb = mKeyguardListener;
-            if (cb != null) {
-                try {
-                    cb.onWallpaperColorsChanged(wallpaper.primaryColors, which);
-                } catch (RemoteException e) {
-                    // Oh well it went away; no big deal
-                }
+        for (int i = 0; i < listeners.length; i++) {
+            try {
+                listeners[i].onWallpaperColorsChanged(wallpaperColors, which);
+            } catch (RemoteException e) {
+                // Callback is gone, it's not necessary to unregister it since
+                // RemoteCallbackList#getBroadcastItem will take care of it.
+            }
+        }
+
+        if (keyguardListener != null) {
+            try {
+                keyguardListener.onWallpaperColorsChanged(wallpaperColors, which);
+            } catch (RemoteException e) {
+                // Oh well it went away; no big deal
             }
         }
     }
@@ -414,6 +423,9 @@
         synchronized (mLock) {
             if (wallpaper.wallpaperId == wallpaperId) {
                 wallpaper.primaryColors = colors;
+                // Now that we have the colors, let's save them into the xml
+                // to avoid having to run this again.
+                saveSettingsLocked(wallpaper.userId);
             } else {
                 Slog.w(TAG, "Not setting primary colors since wallpaper changed");
             }
@@ -1366,6 +1378,7 @@
 
             RuntimeException e = null;
             try {
+                wallpaper.primaryColors = null;
                 wallpaper.imageWallpaperPending = false;
                 if (userId != mCurrentUserId) return;
                 if (bindWallpaperComponentLocked(defaultFailed
@@ -1860,6 +1873,7 @@
             try {
                 wallpaper.imageWallpaperPending = false;
                 if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
+                    wallpaper.primaryColors = null;
                     wallpaper.wallpaperId = makeWallpaperIdLocked();
                     notifyCallbacksLocked(wallpaper);
                     shouldNotifyColors = true;
@@ -1996,7 +2010,6 @@
             }
             wallpaper.wallpaperComponent = componentName;
             wallpaper.connection = newConn;
-            wallpaper.primaryColors = null;
             newConn.mReply = reply;
             try {
                 if (wallpaper.userId == mCurrentUserId) {
@@ -2202,7 +2215,7 @@
                     out.attribute(null, "colorValue"+i, Integer.toString(wc.toArgb()));
                 }
             }
-            out.attribute(null, "supportsDarkText",
+            out.attribute(null, "colorHints",
                     Integer.toString(wallpaper.primaryColors.getColorHints()));
         }
 
@@ -2439,7 +2452,6 @@
         int colorsCount = getAttributeInt(parser, "colorsCount", 0);
         if (colorsCount > 0) {
             Color primary = null, secondary = null, tertiary = null;
-            final List<Color> colors = new ArrayList<>();
             for (int i = 0; i < colorsCount; i++) {
                 Color color = Color.valueOf(getAttributeInt(parser, "colorValue" + i, 0));
                 if (i == 0) {
@@ -2616,6 +2628,7 @@
                 pw.print("  mCropHint="); pw.println(wallpaper.cropHint);
                 pw.print("  mPadding="); pw.println(wallpaper.padding);
                 pw.print("  mName=");  pw.println(wallpaper.name);
+                pw.print("  mAllowBackup="); pw.println(wallpaper.allowBackup);
                 pw.print("  mWallpaperComponent="); pw.println(wallpaper.wallpaperComponent);
                 if (wallpaper.connection != null) {
                     WallpaperConnection conn = wallpaper.connection;
@@ -2646,6 +2659,7 @@
                 pw.print("  mCropHint="); pw.println(wallpaper.cropHint);
                 pw.print("  mPadding="); pw.println(wallpaper.padding);
                 pw.print("  mName=");  pw.println(wallpaper.name);
+                pw.print("  mAllowBackup="); pw.println(wallpaper.allowBackup);
             }
 
         }
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index a0381f7..bf769ed 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -296,7 +296,10 @@
 
     @Override
     public boolean isMultiProcessDefaultEnabled() {
-        return true;
+        // Multiprocess is enabled for all 64-bit devices, since the ability to run the renderer
+        // process in 32-bit when it's a separate process typically results in a net memory saving.
+        // Multiprocess is also enabled for 32-bit devices unless they report they are "low ram".
+        return Build.SUPPORTED_64_BIT_ABIS.length > 0 || !ActivityManager.isLowRamDeviceStatic();
     }
 
     // flags declaring we want extra info from the package manager for webview providers
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index f769261..f3a09ed 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -350,7 +350,7 @@
 
     // This must be called while inside a transaction.
     boolean stepAnimationLocked(long currentTime) {
-        if (mService.okToDisplay()) {
+        if (mService.okToAnimate()) {
             // We will run animations as long as the display isn't frozen.
 
             if (animation == sDummyAnimation) {
@@ -416,6 +416,7 @@
         if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + mAppToken
                 + ": reportedVisible=" + mAppToken.reportedVisible
                 + " okToDisplay=" + mService.okToDisplay()
+                + " okToAnimate=" + mService.okToAnimate()
                 + " startingDisplayed=" + mAppToken.startingDisplayed);
 
         transformation.clear();
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 4e4398e..86e130d 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -436,7 +436,7 @@
 
             // If we are preparing an app transition, then delay changing
             // the visibility of this token until we execute that transition.
-            if (mService.okToDisplay() && mService.mAppTransition.isTransitionSet()) {
+            if (mService.okToAnimate() && mService.mAppTransition.isTransitionSet()) {
                 // A dummy animation is a placeholder animation which informs others that an
                 // animation is going on (in this case an application transition). If the animation
                 // was transferred from another application/animator, no dummy animator should be
@@ -647,7 +647,23 @@
         return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation();
     }
 
-    public void removeStartingWindow() {
+    /**
+     * Remove starting window if the app is currently hidden. It is possible the starting window is
+     * part of its app exit transition animation in which case we delay hiding the app token. The
+     * method allows for removal when window manager has set the app token to hidden.
+     */
+    public void removeHiddenStartingWindow() {
+        synchronized (mWindowMap) {
+            if (!mContainer.hidden) {
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Starting window app still visible."
+                        + " Ignoring remove request.");
+                return;
+            }
+            removeStartingWindow();
+        }
+    }
+
+    void removeStartingWindow() {
         synchronized (mWindowMap) {
             if (mHandler.hasCallbacks(mRemoveStartingWindow)) {
                 // Already scheduled.
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index ce44dab8..839ee0e 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -441,6 +441,7 @@
                     mChildren.get(i).mWinAnimator.hide("immediately hidden");
                 }
                 SurfaceControl.closeTransaction();
+                removeStartingWindow();
             }
 
             if (!mService.mClosingApps.contains(this) && !mService.mOpeningApps.contains(this)) {
@@ -518,6 +519,12 @@
         return super.checkCompleteDeferredRemoval();
     }
 
+    private void removeStartingWindow() {
+        if (startingData != null && getController() != null) {
+            getController().removeStartingWindow();
+        }
+    }
+
     void onRemovedFromDisplay() {
         if (mRemovingFromDisplay) {
             return;
@@ -545,9 +552,7 @@
         if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
                 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
 
-        if (startingData != null && getController() != null) {
-            getController().removeStartingWindow();
-        }
+        removeStartingWindow();
 
         // If this window was animating, then we need to ensure that the app transition notifies
         // that animations have completed in WMS.handleAnimatingStoppedAndTransitionLocked(), so
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index 49f5ee6..7414928 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -290,7 +290,7 @@
             state.dimLayer.setLayer(dimLayer);
         }
         if (state.dimLayer.isAnimating()) {
-            if (!mDisplayContent.mService.okToDisplay()) {
+            if (!mDisplayContent.mService.okToAnimate()) {
                 // Jump to the end of the animation.
                 state.dimLayer.show();
             } else {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 05f4626..9fe7381 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1073,7 +1073,7 @@
             }
             if (w.mHasSurface && !rotateSeamlessly) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w);
-                w.setOrientationChanging(true);
+                w.mOrientationChanging = true;
                 mService.mRoot.mOrientationChangeComplete = false;
                 w.mLastFreezeDuration = 0;
             }
@@ -2679,10 +2679,10 @@
         mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
 
         forAllWindows(w -> {
-            if (!w.getOrientationChanging()) {
+            if (!w.mOrientationChanging) {
                 return;
             }
-            w.setOrientationChanging(false);
+            w.mOrientationChanging = false;
             w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                     - mService.mDisplayFreezeTime);
             Slog.w(TAG_WM, "Force clearing orientation change: " + w);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f9c21b3..730c08c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1445,6 +1445,9 @@
                 }
             }
 
+            final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
+            win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
+
             final AppWindowToken aToken = token.asAppWindowToken();
             if (type == TYPE_APPLICATION_STARTING && aToken != null) {
                 aToken.startingWindow = win;
@@ -2326,7 +2329,7 @@
         // artifacts when we unfreeze the display if some different animation
         // is running.
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
-        if (okToDisplay()) {
+        if (okToAnimate()) {
             final DisplayContent displayContent = atoken.getTask().getDisplayContent();
             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
             final int width = displayInfo.appWidth;
@@ -2406,6 +2409,10 @@
         return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn();
     }
 
+    boolean okToAnimate() {
+        return okToDisplay() && mPolicy.isInteractive();
+    }
+
     @Override
     public void addWindowToken(IBinder binder, int type, int displayId) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
@@ -2672,7 +2679,7 @@
         synchronized(mWindowMap) {
             boolean prepared = mAppTransition.prepareAppTransitionLocked(transit, alwaysKeepCurrent,
                     flags, forceOverride);
-            if (prepared && okToDisplay()) {
+            if (prepared && okToAnimate()) {
                 mSkipAppTransitionAnimation = false;
             }
         }
@@ -5789,7 +5796,7 @@
         // orientation.
         if (!okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
             if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
-            w.setOrientationChanging(true);
+            w.mOrientationChanging = true;
             w.mLastFreezeDuration = 0;
             mRoot.mOrientationChangeComplete = false;
             if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 17768e6..92e8f49 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -446,7 +446,7 @@
      * Set when the orientation is changing and this window has not yet
      * been updated for the new orientation.
      */
-    private boolean mOrientationChanging;
+    boolean mOrientationChanging;
 
     /**
      * The orientation during the last visible call to relayout. If our
@@ -1189,8 +1189,7 @@
             // then we need to hold off on unfreezing the display until this window has been
             // redrawn; to do that, we need to go through the process of getting informed by the
             // application when it has finished drawing.
-            if (getOrientationChanging() || dragResizingChanged
-                    || isResizedWhileNotDragResizing()) {
+            if (mOrientationChanging || dragResizingChanged || isResizedWhileNotDragResizing()) {
                 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
                     Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
                             + ", mDrawState=DRAW_PENDING in " + this
@@ -1205,33 +1204,17 @@
                 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this);
                 mService.mResizingWindows.add(this);
             }
-        } else if (getOrientationChanging()) {
+        } else if (mOrientationChanging) {
             if (isDrawnLw()) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in "
                         + this + ", surfaceController " + winAnimator.mSurfaceController);
-                setOrientationChanging(false);
+                mOrientationChanging = false;
                 mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                         - mService.mDisplayFreezeTime);
             }
         }
     }
 
-    boolean getOrientationChanging() {
-        // In addition to the local state flag, we must also consider the difference in the last
-        // reported configuration vs. the current state. If the client code has not been informed of
-        // the change, logic dependent on having finished processing the orientation, such as
-        // unfreezing, could be improperly triggered.
-        // TODO(b/62846907): Checking against {@link mLastReportedConfiguration} could be flaky as
-        //                   this is not necessarily what the client has processed yet. Find a
-        //                   better indicator consistent with the client.
-        return mOrientationChanging
-                || getConfiguration().orientation != mLastReportedConfiguration.orientation;
-    }
-
-    void setOrientationChanging(boolean changing) {
-        mOrientationChanging = changing;
-    }
-
     DisplayContent getDisplayContent() {
         return mToken.getDisplayContent();
     }
@@ -1683,7 +1666,7 @@
         final boolean adjustedForMinimizedDockOrIme = task != null
                 && (task.mStack.isAdjustedForMinimizedDockedStack()
                 || task.mStack.isAdjustedForIme());
-        if (mService.okToDisplay()
+        if (mService.okToAnimate()
                 && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
                 && !isDragResizing() && !adjustedForMinimizedDockOrIme
                 && (task == null || getTask().mStack.hasMovementAnimations())
@@ -1852,7 +1835,7 @@
         // 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 (mHasSurface && mService.okToDisplay()) {
+        if (mHasSurface && mService.okToAnimate()) {
             if (mWillReplaceWindow) {
                 // This window is going to be replaced. We need to keep it around until the new one
                 // gets added, then we will get rid of this one.
@@ -1992,6 +1975,12 @@
             return false;
         }
 
+        final boolean windowsAreFocusable = mAppToken != null && mAppToken.windowsAreFocusable();
+        if (!windowsAreFocusable) {
+            // This window can't be an IME target if the app's windows should not be focusable.
+            return false;
+        }
+
         final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
         final int type = mAttrs.type;
 
@@ -2276,7 +2265,7 @@
             mLayoutNeeded = true;
         }
 
-        if (isDrawnLw() && mService.okToDisplay()) {
+        if (isDrawnLw() && mService.okToAnimate()) {
             mWinAnimator.applyEnterAnimationLocked();
         }
     }
@@ -2432,7 +2421,7 @@
         if (doAnimation) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
                     + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation);
-            if (!mService.okToDisplay()) {
+            if (!mService.okToAnimate()) {
                 doAnimation = false;
             } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) {
                 // Check for the case where we are currently visible and
@@ -2462,7 +2451,7 @@
 
     boolean hideLw(boolean doAnimation, boolean requestAnim) {
         if (doAnimation) {
-            if (!mService.okToDisplay()) {
+            if (!mService.okToAnimate()) {
                 doAnimation = false;
             }
         }
@@ -2705,10 +2694,10 @@
 
         mAppFreezing = false;
 
-        if (mHasSurface && !getOrientationChanging()
+        if (mHasSurface && !mOrientationChanging
                 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
             if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this);
-            setOrientationChanging(true);
+            mOrientationChanging = true;
             mService.mRoot.mOrientationChangeComplete = false;
         }
         mLastFreezeDuration = 0;
@@ -3127,7 +3116,7 @@
             mWinAnimator.mSurfaceResized = false;
             mReportOrientationChanged = false;
         } catch (RemoteException e) {
-            setOrientationChanging(false);
+            mOrientationChanging = false;
             mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                     - mService.mDisplayFreezeTime);
             // We are assuming the hosting process is dead or in a zombie state.
@@ -3488,13 +3477,10 @@
                     pw.print(" mDestroying="); pw.print(mDestroying);
                     pw.print(" mRemoved="); pw.println(mRemoved);
         }
-        if (getOrientationChanging() || mAppFreezing || mTurnOnScreen
+        if (mOrientationChanging || mAppFreezing || mTurnOnScreen
                 || mReportOrientationChanged) {
             pw.print(prefix); pw.print("mOrientationChanging=");
                     pw.print(mOrientationChanging);
-                    pw.print(" configOrientationChanging=");
-                    pw.print(mLastReportedConfiguration.orientation
-                            != getConfiguration().orientation);
                     pw.print(" mAppFreezing="); pw.print(mAppFreezing);
                     pw.print(" mTurnOnScreen="); pw.print(mTurnOnScreen);
                     pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index df30cfc..cd55156 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -368,7 +368,7 @@
         // we just started or just stopped animating by comparing mWasAnimating with isAnimationSet().
         mWasAnimating = mAnimating;
         final DisplayContent displayContent = mWin.getDisplayContent();
-        if (displayContent != null && mService.okToDisplay()) {
+        if (displayContent != null && mService.okToAnimate()) {
             // We will run animations as long as the display isn't frozen.
 
             if (mWin.isDrawnLw() && mAnimation != null) {
@@ -1527,11 +1527,11 @@
 
             // There is no need to wait for an animation change if our window is gone for layout
             // already as we'll never be visible.
-            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
+            if (w.mOrientationChanging && w.isGoneForLayoutLw()) {
                 if (DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Orientation change skips hidden " + w);
                 }
-                w.setOrientationChanging(false);
+                w.mOrientationChanging = false;
             }
             return;
         }
@@ -1564,8 +1564,8 @@
             // really hidden (gone for layout), there is no point in still waiting for it.
             // Note that this does introduce a potential glitch if the window becomes unhidden
             // before it has drawn for the new orientation.
-            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
-                w.setOrientationChanging(false);
+            if (w.mOrientationChanging && w.isGoneForLayoutLw()) {
+                w.mOrientationChanging = false;
                 if (DEBUG_ORIENTATION) Slog.v(TAG,
                         "Orientation change skips hidden " + w);
             }
@@ -1618,7 +1618,7 @@
                     mAnimator.setPendingLayoutChanges(w.getDisplayId(),
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
                 } else {
-                    w.setOrientationChanging(false);
+                    w.mOrientationChanging = false;
                 }
             }
             if (hasSurface()) {
@@ -1631,14 +1631,14 @@
             displayed = true;
         }
 
-        if (w.getOrientationChanging()) {
+        if (w.mOrientationChanging) {
             if (!w.isDrawnLw()) {
                 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
                 mAnimator.mLastWindowFreezeSource = w;
                 if (DEBUG_ORIENTATION) Slog.v(TAG,
                         "Orientation continue waiting for draw in " + w);
             } else {
-                w.setOrientationChanging(false);
+                w.mOrientationChanging = false;
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
             }
         }
@@ -1781,7 +1781,7 @@
         // artifacts when we unfreeze the display if some different animation
         // is running.
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#applyAnimationLocked");
-        if (mService.okToDisplay()) {
+        if (mService.okToAnimate()) {
             int anim = mPolicy.selectAnimationLw(mWin, transit);
             int attr = -1;
             Animation a = null;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 68349a1..72a832a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -526,7 +526,7 @@
         // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead.
         Set<String> mOwnerInstalledCaCerts = new ArraySet<>();
 
-        // Used for initialization of users created by createAndManageUsers.
+        // Used for initialization of users created by createAndManageUser.
         boolean mAdminBroadcastPending = false;
         PersistableBundle mInitBundle = null;
 
@@ -4249,6 +4249,7 @@
             mInjector.binderRestoreCallingIdentity(token);
         }
     }
+
     @Override
     public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException {
         final int callingUid = mInjector.binderGetCallingUid();
@@ -7369,9 +7370,8 @@
 
     private void enableIfNecessary(String packageName, int userId) {
         try {
-            ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName,
-                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
-                    userId);
+            final ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName,
+                    PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId);
             if (ai.enabledSetting
                     == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
                 mIPackageManager.setApplicationEnabledSetting(packageName,
@@ -8125,8 +8125,10 @@
         if (!mInjector.binderGetCallingUserHandle().isSystem()) {
             throw new SecurityException("createAndManageUser was called from non-system user");
         }
-        if (!mInjector.userManagerIsSplitSystemUser()
-                && (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) {
+        final boolean ephemeral = (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0;
+        final boolean demo = (flags & DevicePolicyManager.MAKE_USER_DEMO) != 0
+                && UserManager.isDeviceInDemoMode(mContext);
+        if (ephemeral && !mInjector.userManagerIsSplitSystemUser() && !demo) {
             throw new IllegalArgumentException(
                     "Ephemeral users are only supported on systems with a split system user.");
         }
@@ -8138,9 +8140,12 @@
             final long id = mInjector.binderClearCallingIdentity();
             try {
                 int userInfoFlags = 0;
-                if ((flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) {
+                if (ephemeral) {
                     userInfoFlags |= UserInfo.FLAG_EPHEMERAL;
                 }
+                if (demo) {
+                    userInfoFlags |= UserInfo.FLAG_DEMO;
+                }
                 UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name,
                         userInfoFlags);
                 if (userInfo != null) {
@@ -8172,6 +8177,23 @@
                 return null;
             }
 
+            final UserInfo userInfo = getUserInfo(userHandle);
+            if (userInfo != null && userInfo.isDemo()) {
+                try {
+                    final ApplicationInfo ai = mIPackageManager.getApplicationInfo(adminPkg,
+                            PackageManager.MATCH_DISABLED_COMPONENTS, userHandle);
+                    final boolean isSystemApp =
+                            ai != null && (ai.flags & (ApplicationInfo.FLAG_SYSTEM
+                                    | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
+                    if (isSystemApp) {
+                        mIPackageManager.setApplicationEnabledSetting(adminPkg,
+                                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                                PackageManager.DONT_KILL_APP, userHandle, "DevicePolicyManager");
+                    }
+                } catch (RemoteException e) {
+                }
+            }
+
             setActiveAdmin(profileOwner, true, userHandle);
             // User is not started yet, the broadcast by setActiveAdmin will not be received.
             // So we store adminExtras for broadcasting when the user starts for first time.
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ed52326..d5e0eb0 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -171,6 +171,8 @@
             "com.android.server.wifi.aware.WifiAwareService";
     private static final String WIFI_P2P_SERVICE_CLASS =
             "com.android.server.wifi.p2p.WifiP2pService";
+    private static final String LOWPAN_SERVICE_CLASS =
+            "com.android.server.lowpan.LowpanService";
     private static final String ETHERNET_SERVICE_CLASS =
             "com.android.server.ethernet.EthernetService";
     private static final String JOB_SCHEDULER_SERVICE_CLASS =
@@ -1089,6 +1091,13 @@
                     traceEnd();
                 }
 
+                if (context.getPackageManager().hasSystemFeature(
+                        PackageManager.FEATURE_LOWPAN)) {
+                    traceBeginAndSlog("StartLowpan");
+                    mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
+                    traceEnd();
+                }
+
                 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
                     mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
                     traceBeginAndSlog("StartEthernet");
diff --git a/services/net/OWNERS b/services/net/OWNERS
new file mode 100644
index 0000000..fa26997
--- /dev/null
+++ b/services/net/OWNERS
@@ -0,0 +1,7 @@
+set noparent
+
+per-file Android.mk = build.master@android.com
+
+ek@google.com
+hugobenichi@google.com
+lorenzo@google.com
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 48fa970..41fccdb 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -1064,7 +1064,7 @@
             mNwService.setIPv6AddrGenMode(mInterfaceName, mConfiguration.mIPv6AddrGenMode);
         } catch (ServiceSpecificException e) {
             if (e.errorCode != OsConstants.EOPNOTSUPP) {
-                throw e;
+                logError("Unable to set IPv6 addrgen mode: %s", e);
             }
         }
     }
diff --git a/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
index 5ed8210..faf6a9b 100644
--- a/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
+++ b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
@@ -42,31 +42,31 @@
 
     @Test
     public void testFirstAlertAllowed() throws Exception {
-        assertFalse(mLimiter.isRateLimited(mTestStartTime));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
     }
 
     @Test
     public void testAllowedAfterSecond() throws Exception {
-        assertFalse(mLimiter.isRateLimited(mTestStartTime));
-        assertFalse(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL));
     }
 
     @Test
     public void testAllowedAfterSecondEvenWithBlockedEntries() throws Exception {
-        assertFalse(mLimiter.isRateLimited(mTestStartTime));
-        assertTrue(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
-        assertFalse(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL));
     }
 
     @Test
     public void testAllowedDisallowedBeforeSecond() throws Exception {
-        assertFalse(mLimiter.isRateLimited(mTestStartTime));
-        assertTrue(mLimiter.isRateLimited(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
     }
 
     @Test
     public void testDisallowedTimePast() throws Exception {
-        assertFalse(mLimiter.isRateLimited(mTestStartTime));
-        assertTrue(mLimiter.isRateLimited(mTestStartTime - ALLOWED_ALERT_INTERVAL));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime - ALLOWED_ALERT_INTERVAL));
     }
 }
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 8ff4639..e799427 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -18,6 +18,7 @@
 
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
@@ -85,7 +86,6 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 public class NotificationManagerServiceTest extends NotificationTestCase {
-    private static final long WAIT_FOR_IDLE_TIMEOUT = 2;
     private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
     private final int uid = Binder.getCallingUid();
     private NotificationManagerService mNotificationManagerService;
@@ -109,6 +109,7 @@
     private AudioManager mAudioManager;
     @Mock
     ActivityManager mActivityManager;
+
     private NotificationChannel mTestNotificationChannel = new NotificationChannel(
             TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
     @Mock
@@ -316,7 +317,7 @@
 
         NotificationChannel channel = new NotificationChannel("id", "name",
                 NotificationManager.IMPORTANCE_HIGH);
-        channel.setImportance(NotificationManager.IMPORTANCE_NONE);
+        channel.setImportance(IMPORTANCE_NONE);
         NotificationRecord r = generateNotificationRecord(channel);
         assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats));
         verify(mUsageStats, times(1)).registerBlocked(eq(r));
@@ -483,6 +484,93 @@
     }
 
     @Test
+    public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
+        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+        sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
+        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(sbn.getPackageName());
+        assertEquals(0, notifs.length);
+    }
+
+    @Test
+    public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception {
+        final NotificationRecord notif = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+        notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
+        mNotificationManagerService.addNotification(notif);
+        mNotificationManagerService.cancelAllNotificationsInt(uid, 0, PKG, null, 0, 0, true,
+                notif.getUserId(), 0, null);
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(notif.sbn.getPackageName());
+        assertEquals(0, notifs.length);
+    }
+
+    @Test
+    public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception {
+        final NotificationRecord notif = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+        notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
+        mNotificationManagerService.addNotification(notif);
+
+        mNotificationManagerService.mNotificationDelegate.onClearAll(uid, Binder.getCallingPid(),
+                notif.getUserId());
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(notif.sbn.getPackageName());
+        assertEquals(1, notifs.length);
+    }
+
+    @Test
+    public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception {
+        final NotificationRecord parent = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+        final NotificationRecord child = generateNotificationRecord(
+                mTestNotificationChannel, 2, "group", false);
+        final NotificationRecord child2 = generateNotificationRecord(
+                mTestNotificationChannel, 3, "group", false);
+        child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
+        final NotificationRecord newGroup = generateNotificationRecord(
+                mTestNotificationChannel, 4, "group2", false);
+        mNotificationManagerService.addNotification(parent);
+        mNotificationManagerService.addNotification(child);
+        mNotificationManagerService.addNotification(child2);
+        mNotificationManagerService.addNotification(newGroup);
+        mNotificationManagerService.getBinderService().cancelNotificationsFromListener(null, null);
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+        assertEquals(1, notifs.length);
+    }
+
+    @Test
+    public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception {
+        final NotificationRecord parent = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+        final NotificationRecord child = generateNotificationRecord(
+                mTestNotificationChannel, 2, "group", false);
+        final NotificationRecord child2 = generateNotificationRecord(
+                mTestNotificationChannel, 3, "group", false);
+        child2.getNotification().flags |= Notification.FLAG_NO_CLEAR;
+        final NotificationRecord newGroup = generateNotificationRecord(
+                mTestNotificationChannel, 4, "group2", false);
+        mNotificationManagerService.addNotification(parent);
+        mNotificationManagerService.addNotification(child);
+        mNotificationManagerService.addNotification(child2);
+        mNotificationManagerService.addNotification(newGroup);
+        mNotificationManagerService.mNotificationDelegate.onClearAll(uid, Binder.getCallingPid(),
+                parent.getUserId());
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(parent.sbn.getPackageName());
+        assertEquals(1, notifs.length);
+    }
+
+    @Test
     public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -1119,7 +1207,8 @@
     @Test
     public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups()
             throws Exception {
-        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group", false);
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group",
+                false);
         mNotificationManagerService.addNotification(r);
         mNotificationManagerService.addEnqueuedNotification(r);
 
@@ -1130,4 +1219,60 @@
 
         verify(mGroupHelper, never()).onNotificationPosted(any());
     }
+
+    @Test
+    public void testNoFakeColorizedPermission() throws Exception {
+        when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setColorized(true)
+                .setFlag(Notification.FLAG_CAN_COLORIZE, true)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", uid, 0,
+                nb.build(), new UserHandle(uid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        NotificationRecord posted = mNotificationManagerService.findNotificationLocked(
+                PKG, null, nr.sbn.getId(), nr.sbn.getUserId());
+
+        assertFalse(posted.getNotification().isColorized());
+    }
+
+    @Test
+    public void testGetNotificationCountLocked() throws Exception {
+        for (int i = 0; i < 20; i++) {
+            NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, i, null, false);
+            mNotificationManagerService.addEnqueuedNotification(r);
+        }
+        for (int i = 0; i < 20; i++) {
+            NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, i, null, false);
+            mNotificationManagerService.addNotification(r);
+        }
+
+        // another package
+        Notification n =
+                new Notification.Builder(mContext, mTestNotificationChannel.getId())
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", uid, 0,
+                n, new UserHandle(uid), null, 0);
+        NotificationRecord otherPackage =
+                new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+        mNotificationManagerService.addEnqueuedNotification(otherPackage);
+        mNotificationManagerService.addNotification(otherPackage);
+
+        // Same notifications are enqueued as posted, everything counts b/c id and tag don't match
+        assertEquals(40, mNotificationManagerService.getNotificationCountLocked(PKG, new UserHandle(uid).getIdentifier(), 0, null));
+        assertEquals(40, mNotificationManagerService.getNotificationCountLocked(PKG, new UserHandle(uid).getIdentifier(), 0, "tag2"));
+        assertEquals(2, mNotificationManagerService.getNotificationCountLocked("a", new UserHandle(uid).getIdentifier(), 0, "banana"));
+
+        // exclude a known notification - it's excluded from only the posted list, not enqueued
+        assertEquals(39, mNotificationManagerService.getNotificationCountLocked(PKG, new UserHandle(uid).getIdentifier(), 0, "tag"));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/KeyboardInterceptorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/KeyboardInterceptorTest.java
new file mode 100644
index 0000000..5db397f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/KeyboardInterceptorTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2017 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.accessibility;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import android.os.Looper;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.KeyEvent;
+import android.view.WindowManagerPolicy;
+import android.view.WindowManagerPolicy.WindowState;
+
+/**
+ * Tests for KeyboardInterceptor
+ */
+@RunWith(AndroidJUnit4.class)
+public class KeyboardInterceptorTest {
+    private KeyboardInterceptor mInterceptor;
+    private MessageCapturingHandler mHandler = new MessageCapturingHandler(
+            msg -> mInterceptor.handleMessage(msg));
+    @Mock AccessibilityManagerService mMockAms;
+    @Mock WindowManagerPolicy mMockPolicy;
+
+    @BeforeClass
+    public static void oneTimeInitialization() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mInterceptor = new KeyboardInterceptor(mMockAms, mMockPolicy, mHandler);
+    }
+
+    @Test
+    public void whenNonspecialKeyArrives_withNothingInQueue_eventGoesToAms() {
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
+        mInterceptor.onKeyEvent(event, 0);
+        verify(mMockAms).notifyKeyEvent(argThat(matchesKeyEvent(event)), eq(0));
+    }
+
+    @Test
+    public void whenVolumeKeyArrives_andPolicySaysUseIt_eventGoesToAms() {
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_DOWN);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(event)), eq(0))).thenReturn(0L);
+        mInterceptor.onKeyEvent(event, 0);
+        verify(mMockAms).notifyKeyEvent(argThat(matchesKeyEvent(event)), eq(0));
+    }
+
+    @Test
+    public void whenVolumeKeyArrives_andPolicySaysDropIt_eventDropped() {
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(event)), eq(0))).thenReturn(-1L);
+        mInterceptor.onKeyEvent(event, 0);
+        verify(mMockAms, times(0)).notifyKeyEvent(anyObject(), anyInt());
+        assertFalse(mHandler.hasMessages());
+    }
+
+    @Test
+    public void whenVolumeKeyArrives_andPolicySaysDelayThenUse_eventQueuedThenSentToAms() {
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(event)), eq(0))).thenReturn(150L);
+        mInterceptor.onKeyEvent(event, 0);
+
+        assertTrue(mHandler.hasMessages());
+        verify(mMockAms, times(0)).notifyKeyEvent(anyObject(), anyInt());
+
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(event)), eq(0))).thenReturn(0L);
+        mHandler.sendAllMessages();
+
+        verify(mMockAms).notifyKeyEvent(argThat(matchesKeyEvent(event)), eq(0));
+    }
+
+    @Test
+    public void whenVolumeKeyArrives_andPolicySaysDelayThenDrop_eventQueuedThenDropped() {
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_DOWN);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(event)), eq(0))).thenReturn(150L);
+        mInterceptor.onKeyEvent(event, 0);
+
+        assertTrue(mHandler.hasMessages());
+        verify(mMockAms, times(0)).notifyKeyEvent(anyObject(), anyInt());
+
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(event)), eq(0))).thenReturn(-1L);
+        mHandler.sendAllMessages();
+
+        verify(mMockAms, times(0)).notifyKeyEvent(anyObject(), anyInt());
+    }
+
+    @Test
+    public void whenSomeEventsGetDelayed_allEventsStillInOrder() {
+        KeyEvent[] events = {new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0),
+                new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP),
+                new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A),
+                new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_VOLUME_UP),
+                new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0)};
+
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[1])), eq(0))).thenReturn(150L);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[3])), eq(0))).thenReturn(75L);
+
+        for (KeyEvent event : events) {
+            mInterceptor.onKeyEvent(event, 0);
+        }
+
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[1])), eq(0))).thenReturn(0L);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[3])), eq(0))).thenReturn(0L);
+
+        mHandler.sendAllMessages();
+
+        InOrder inOrder = Mockito.inOrder(mMockAms);
+        for (KeyEvent event : events) {
+            inOrder.verify(mMockAms).notifyKeyEvent(argThat(matchesKeyEvent(event)), eq(0));
+        }
+    }
+
+    @Test
+    public void whenSomeEventsGetDropped_otherEventsStillInOrder() {
+        KeyEvent[] events = {new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0),
+                new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP),
+                new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A),
+                new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_VOLUME_UP),
+                new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0)};
+
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[1])), eq(0))).thenReturn(150L);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[3])), eq(0))).thenReturn(75L);
+
+        for (KeyEvent event : events) {
+            mInterceptor.onKeyEvent(event, 0);
+        }
+
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[1])), eq(0))).thenReturn(-1L);
+        when(mMockPolicy.interceptKeyBeforeDispatching((WindowState) argThat(nullValue()),
+                argThat(matchesKeyEvent(events[3])), eq(0))).thenReturn(-1L);
+
+        mHandler.sendAllMessages();
+
+        InOrder inOrder = Mockito.inOrder(mMockAms);
+        for (KeyEvent event : events) {
+            if ((event == events[1]) || (event == events[3])) continue;
+            inOrder.verify(mMockAms).notifyKeyEvent(argThat(matchesKeyEvent(event)), eq(0));
+        }
+    }
+
+    private static KeyEventMatcher matchesKeyEvent(KeyEvent event) {
+        return new KeyEventMatcher(event);
+    }
+
+    private static class KeyEventMatcher extends TypeSafeMatcher<KeyEvent> {
+        private KeyEvent mEventToMatch;
+
+        public KeyEventMatcher(KeyEvent eventToMatch) {
+            mEventToMatch = eventToMatch;
+        }
+
+        @Override
+        protected boolean matchesSafely(KeyEvent item) {
+            return (mEventToMatch.getKeyCode() == item.getKeyCode())
+                    && (mEventToMatch.getAction() == item.getAction());
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Matches key event");
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 6701b71..0ffc61a 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -113,7 +113,7 @@
     private static final int[] UID_RECORD_CHANGES = {
         UidRecord.CHANGE_PROCSTATE,
         UidRecord.CHANGE_GONE,
-        UidRecord.CHANGE_GONE_IDLE,
+        UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE,
         UidRecord.CHANGE_IDLE,
         UidRecord.CHANGE_ACTIVE
     };
@@ -417,7 +417,7 @@
                 // delivered to this observer.
                 final int[] changesToVerify = {
                     UidRecord.CHANGE_IDLE,
-                    UidRecord.CHANGE_GONE_IDLE
+                    UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE
                 };
                 verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
                         (observer, changeItem) -> {
@@ -439,7 +439,7 @@
                 // delivered to this observer.
                 final int[] changesToVerify = {
                         UidRecord.CHANGE_GONE,
-                        UidRecord.CHANGE_GONE_IDLE
+                        UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE
                 };
                 verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
                         (observer, changeItem) -> {
@@ -585,7 +585,7 @@
         for (int i = 0; i < pendingItemsForUids.size(); ++i) {
             final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
             final UidRecord validateUidRecord = mAms.mValidateUids.get(item.uid);
-            if (item.change == UidRecord.CHANGE_GONE || item.change == UidRecord.CHANGE_GONE_IDLE) {
+            if ((item.change & UidRecord.CHANGE_GONE) != 0) {
                 assertNull("validateUidRecord should be null since the change is either "
                         + "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord);
             } else {
@@ -614,7 +614,8 @@
             final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
             // Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd
             // distribution for this assignment.
-            item.change = (i % 2) == 0 ? UidRecord.CHANGE_GONE_IDLE : UidRecord.CHANGE_GONE;
+            item.change = (i % 2) == 0 ? (UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE)
+                    : UidRecord.CHANGE_GONE;
         }
         mAms.mPendingUidChanges.addAll(pendingItemsForUids);
         mAms.dispatchUidsChanged();
@@ -653,8 +654,7 @@
             mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
             // Verify there is no effect on curProcStateSeq.
             assertEquals(curProcstateSeq, uidRecord.curProcStateSeq);
-            if (changeToDispatch == UidRecord.CHANGE_GONE
-                    || changeToDispatch == UidRecord.CHANGE_GONE_IDLE) {
+            if ((changeToDispatch & UidRecord.CHANGE_GONE) != 0) {
                 // Since the change is CHANGE_GONE or CHANGE_GONE_IDLE, verify that
                 // lastProcStateSeqDispatchedToObservers is not updated.
                 assertNotEquals(uidRecord.curProcStateSeq,
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index faa91b8..3866e0ed 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -34,6 +34,7 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.nullable;
 import static org.mockito.Mockito.reset;
@@ -53,6 +54,7 @@
 import android.app.admin.PasswordMetrics;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -338,7 +340,7 @@
         // Next, add one more admin.
         // Before doing so, update the application info, now it's enabled.
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID,
-                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+                PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
 
         dpm.setActiveAdmin(admin2, /* replace =*/ false);
 
@@ -380,6 +382,74 @@
         mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
     }
 
+    public void testCreateAndManageUser_demoUserSystemApp() throws Exception {
+        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+
+        setDeviceOwner();
+
+        final int id = UserHandle.getUserId(DpmMockContext.CALLER_UID);
+
+        final UserInfo demoUserInfo = mock(UserInfo.class);
+        demoUserInfo.id = id;
+        doReturn(UserHandle.of(id)).when(demoUserInfo).getUserHandle();
+        doReturn(true).when(demoUserInfo).isDemo();
+        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        doReturn(demoUserInfo).when(um).getUserInfo(id);
+        doReturn(demoUserInfo).when(mContext.getUserManagerInternal())
+                .createUserEvenWhenDisallowed(anyString(), anyInt());
+
+        final ApplicationInfo applicationInfo = getServices().ipackageManager.getApplicationInfo(
+                admin2.getPackageName(), PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, id);
+        applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+        doReturn(applicationInfo).when(getServices().ipackageManager).getApplicationInfo(
+                anyString(), anyInt(), anyInt());
+
+        final UserHandle userHandle = dpm.createAndManageUser(admin1, "", admin2, null, 0);
+
+        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
+                eq(admin2.getPackageName()),
+                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+                eq(PackageManager.DONT_KILL_APP),
+                eq(id),
+                anyString());
+
+        assertNotNull(userHandle);
+    }
+
+    public void testCreateAndManageUser_demoUserSystemUpdatedApp() throws Exception {
+        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+
+        setDeviceOwner();
+
+        final int id = UserHandle.getUserId(DpmMockContext.CALLER_UID);
+
+        final UserInfo demoUserInfo = mock(UserInfo.class);
+        demoUserInfo.id = id;
+        doReturn(UserHandle.of(id)).when(demoUserInfo).getUserHandle();
+        doReturn(true).when(demoUserInfo).isDemo();
+        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        doReturn(demoUserInfo).when(um).getUserInfo(id);
+        doReturn(demoUserInfo).when(mContext.getUserManagerInternal())
+                .createUserEvenWhenDisallowed(anyString(), anyInt());
+
+        final ApplicationInfo applicationInfo = getServices().ipackageManager.getApplicationInfo(
+                admin2.getPackageName(), PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, id);
+        applicationInfo.flags = ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+        doReturn(applicationInfo).when(getServices().ipackageManager).getApplicationInfo(
+                anyString(), anyInt(), anyInt());
+
+        final UserHandle userHandle = dpm.createAndManageUser(admin1, "", admin2, null, 0);
+
+        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
+                eq(admin2.getPackageName()),
+                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+                eq(PackageManager.DONT_KILL_APP),
+                eq(id),
+                anyString());
+
+        assertNotNull(userHandle);
+    }
+
     public void testSetActiveAdmin_multiUsers() throws Exception {
 
         final int ANOTHER_USER_ID = 100;
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 408ee9c..9702118 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -29,6 +29,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.os.UserManagerInternal;
 import android.test.mock.MockContext;
 import android.util.ArrayMap;
 
@@ -196,6 +197,10 @@
         return mMockSystemServices.packageManager;
     }
 
+    public UserManagerInternal getUserManagerInternal() {
+        return mMockSystemServices.userManagerInternal;
+    }
+
     @Override
     public void enforceCallingOrSelfPermission(String permission, String message) {
         if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index e9674f0..13cf9df 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -27,6 +27,7 @@
 import android.app.IActivityManager;
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
+import android.app.trust.TrustManager;
 import android.content.ComponentName;
 import android.content.pm.UserInfo;
 import android.os.FileUtils;
@@ -38,6 +39,7 @@
 import android.security.KeyStore;
 import android.test.AndroidTestCase;
 
+import com.android.internal.widget.ILockSettings;
 import com.android.internal.widget.LockPatternUtils;
 
 import org.mockito.invocation.InvocationOnMock;
@@ -67,7 +69,7 @@
     LockSettingsStorageTestable mStorage;
 
     LockPatternUtils mLockPatternUtils;
-    MockGateKeeperService mGateKeeperService;
+    FakeGateKeeperService mGateKeeperService;
     NotificationManager mNotificationManager;
     UserManager mUserManager;
     FakeStorageManager mStorageManager;
@@ -80,8 +82,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
-        mLockPatternUtils = mock(LockPatternUtils.class);
-        mGateKeeperService = new MockGateKeeperService();
+        mGateKeeperService = new FakeGateKeeperService();
         mNotificationManager = mock(NotificationManager.class);
         mUserManager = mock(UserManager.class);
         mStorageManager = new FakeStorageManager();
@@ -89,7 +90,7 @@
         mDevicePolicyManager = mock(DevicePolicyManager.class);
 
         mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
-                mDevicePolicyManager, mock(StorageManager.class));
+                mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class));
         mStorage = new LockSettingsStorageTestable(mContext,
                 new File(getContext().getFilesDir(), "locksettings"));
         File storageDir = mStorage.mStorageDir;
@@ -99,6 +100,12 @@
             storageDir.mkdirs();
         }
 
+        mLockPatternUtils = new LockPatternUtils(mContext) {
+            @Override
+            public ILockSettings getLockSettings() {
+                return mService;
+            }
+        };
         mSpManager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService, mUserManager);
         mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils, mStorage,
                 mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
@@ -122,8 +129,6 @@
             }
         });
 
-        when(mLockPatternUtils.getLockSettings()).thenReturn(mService);
-
         // Adding a fake Device Owner app which will enable escrow token support in LSS.
         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
                 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java b/services/tests/servicestests/src/com/android/server/locksettings/FakeGateKeeperService.java
similarity index 90%
rename from services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
rename to services/tests/servicestests/src/com/android/server/locksettings/FakeGateKeeperService.java
index b89c1d1..094b7af 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/FakeGateKeeperService.java
@@ -28,7 +28,7 @@
 import java.util.Arrays;
 import java.util.Random;
 
-public class MockGateKeeperService implements IGateKeeperService {
+public class FakeGateKeeperService implements IGateKeeperService {
     static class VerifyHandle {
         public byte[] password;
         public long sid;
@@ -92,7 +92,6 @@
     @Override
     public GateKeeperResponse enroll(int uid, byte[] currentPasswordHandle, byte[] currentPassword,
             byte[] desiredPassword) throws android.os.RemoteException {
-
         if (currentPasswordHandle != null) {
             VerifyHandle handle = new VerifyHandle(currentPasswordHandle);
             if (Arrays.equals(currentPassword, handle.password)) {
@@ -101,17 +100,18 @@
                 refreshSid(uid, handle.sid, false);
                 handleMap.put(uid, newHandle.toBytes());
                 return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
-            } else {
+            } else if (currentPassword != null) {
+                // current password is provided but does not match handle, this is an error case.
                 return null;
             }
-        } else {
-            // Untrusted enroll
-            long newSid = new Random().nextLong();
-            VerifyHandle newHandle = new VerifyHandle(desiredPassword, newSid);
-            refreshSid(uid, newSid, true);
-            handleMap.put(uid, newHandle.toBytes());
-            return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
+            // Fall through: password handle is provided, but no password
         }
+        // Untrusted/new enrollment: generate a new SID
+        long newSid = new Random().nextLong();
+        VerifyHandle newHandle = new VerifyHandle(desiredPassword, newSid);
+        refreshSid(uid, newSid, true);
+        handleMap.put(uid, newHandle.toBytes());
+        return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 3a4aa2d..0df834f 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -103,12 +103,10 @@
         public int binderGetCallingUid() {
             return Process.SYSTEM_UID;
         }
-
-
     }
 
     protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
-            LockSettingsStorage storage, MockGateKeeperService gatekeeper, KeyStore keystore,
+            LockSettingsStorage storage, FakeGateKeeperService gatekeeper, KeyStore keystore,
             IStorageManager storageManager, IActivityManager mActivityManager,
             SyntheticPasswordManager spManager) {
         super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
@@ -137,4 +135,5 @@
         }
         return new String(storedData);
     }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index cb32492..e12f6d3b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -26,12 +26,13 @@
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
 
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.service.gatekeeper.GateKeeperResponse;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.VerifyCredentialResponse;
 import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
-import com.android.server.locksettings.MockGateKeeperService.VerifyHandle;
+import com.android.server.locksettings.FakeGateKeeperService.VerifyHandle;
 
 /**
  * runtest frameworks-services -c com.android.server.locksettings.LockSettingsServiceTests
@@ -80,13 +81,6 @@
         } catch (RemoteException expected) {
             assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
         }
-        try {
-            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, null,
-                    PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
-            fail("Did not fail when enrolling using incorrect credential");
-        } catch (RemoteException expected) {
-            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
-        }
         assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
     }
 
@@ -101,9 +95,10 @@
     }
 
     public void testManagedProfileUnifiedChallenge() throws RemoteException {
-        final String UnifiedPassword = "testManagedProfileUnifiedChallenge-pwd";
-        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+        final String firstUnifiedPassword = "testManagedProfileUnifiedChallenge-pwd-1";
+        final String secondUnifiedPassword = "testManagedProfileUnifiedChallenge-pwd-2";
+        mService.setLockCredential(firstUnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
@@ -121,7 +116,7 @@
         mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
         // verify credential
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
+                firstUnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
                 .getResponseCode());
 
         // Verify that we have a new auth token for the profile
@@ -137,15 +132,15 @@
          */
         mStorageManager.setIgnoreBadUnlock(true);
         // Change primary password and verify that profile SID remains
-        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                UnifiedPassword, PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mService.setLockCredential(secondUnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                firstUnifiedPassword, PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
         mStorageManager.setIgnoreBadUnlock(false);
         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
         assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
 
         // Clear unified challenge
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, UnifiedPassword,
-                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                secondUnifiedPassword, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
@@ -241,14 +236,21 @@
                 type, challenge, userId).getResponseCode());
     }
 
-    private void initializeStorageWithCredential(int userId, String credential, int type, long sid) {
+    private void initializeStorageWithCredential(int userId, String credential, int type, long sid)
+            throws RemoteException {
         byte[] oldHash = new VerifyHandle(credential.getBytes(), sid).toBytes();
-        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
+        if (mService.shouldMigrateToSyntheticPasswordLocked(userId)) {
+            mService.initializeSyntheticPasswordLocked(oldHash, credential, type,
+                    type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? PASSWORD_QUALITY_ALPHABETIC
+                            : PASSWORD_QUALITY_SOMETHING, userId);
         } else {
-            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
-                    LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
+            if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+                mStorage.writeCredentialHash(CredentialHash.create(oldHash,
+                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
+            } else {
+                mStorage.writeCredentialHash(CredentialHash.create(oldHash,
+                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
+            }
         }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index a0578c9..4c77f62 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -22,6 +22,7 @@
 
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
+import android.app.trust.TrustManager;
 import android.content.pm.UserInfo;
 import android.database.sqlite.SQLiteDatabase;
 import android.os.FileUtils;
@@ -74,7 +75,7 @@
 
         MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
                 mock(NotificationManager.class), mock(DevicePolicyManager.class),
-                mock(StorageManager.class));
+                mock(StorageManager.class), mock(TrustManager.class));
         mStorage = new LockSettingsStorageTestable(context,
                 new File(getContext().getFilesDir(), "locksettings"));
         mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
index 8da33a8..3ad30f3 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -18,8 +18,10 @@
 
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
+import android.app.trust.TrustManager;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.pm.PackageManager;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
 
@@ -29,15 +31,17 @@
     private NotificationManager mNotificationManager;
     private DevicePolicyManager mDevicePolicyManager;
     private StorageManager mStorageManager;
+    private TrustManager mTrustManager;
 
     public MockLockSettingsContext(Context base, UserManager userManager,
             NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
-            StorageManager storageManager) {
+            StorageManager storageManager, TrustManager trustManager) {
         super(base);
         mUserManager = userManager;
         mNotificationManager = notificationManager;
         mDevicePolicyManager = devicePolicyManager;
         mStorageManager = storageManager;
+        mTrustManager = trustManager;
     }
 
     @Override
@@ -50,6 +54,8 @@
             return mDevicePolicyManager;
         } else if (STORAGE_SERVICE.equals(name)) {
             return mStorageManager;
+        } else if (TRUST_SERVICE.equals(name)) {
+            return mTrustManager;
         } else {
             throw new RuntimeException("System service not mocked: " + name);
         }
@@ -60,4 +66,8 @@
         // Skip permission checks for unit tests.
     }
 
+    @Override
+    public int checkCallingOrSelfPermission(String permission) {
+        return PackageManager.PERMISSION_GRANTED;
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
index d7468c2..cf03593 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
@@ -32,11 +32,11 @@
 
 public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
 
-    private MockGateKeeperService mGateKeeper;
+    private FakeGateKeeperService mGateKeeper;
     private IWeaver mWeaverService;
 
     public MockSyntheticPasswordManager(LockSettingsStorage storage,
-            MockGateKeeperService gatekeeper, UserManager userManager) {
+            FakeGateKeeperService gatekeeper, UserManager userManager) {
         super(storage, userManager);
         mGateKeeper = gatekeeper;
     }
@@ -88,7 +88,7 @@
 
     @Override
     protected long sidFromPasswordHandle(byte[] handle) {
-        return new MockGateKeeperService.VerifyHandle(handle).sid;
+        return new FakeGateKeeperService.VerifyHandle(handle).sid;
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index ba4ff33..fd77de3 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -72,11 +72,11 @@
         assertNull(result.authToken);
     }
 
-    private void disableSyntheticPassword(int userId) throws RemoteException {
+    private void disableSyntheticPassword() throws RemoteException {
         mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
     }
 
-    private void enableSyntheticPassword(int userId) throws RemoteException {
+    private void enableSyntheticPassword() throws RemoteException {
         mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
     }
 
@@ -87,12 +87,12 @@
     public void testPasswordMigration() throws RemoteException {
         final String PASSWORD = "testPasswordMigration-password";
 
-        disableSyntheticPassword(PRIMARY_USER_ID);
+        disableSyntheticPassword();
         mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
         long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword();
         // Performs migration
         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
                 mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
@@ -106,7 +106,7 @@
     }
 
     private void initializeCredentialUnderSP(String password, int userId) throws RemoteException {
-        enableSyntheticPassword(userId);
+        enableSyntheticPassword();
         int quality = password != null ? PASSWORD_QUALITY_ALPHABETIC
                 : PASSWORD_QUALITY_UNSPECIFIED;
         int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
@@ -198,8 +198,7 @@
 
     public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
         final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd";
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        disableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        disableSyntheticPassword();
         mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
@@ -212,8 +211,7 @@
         assertTrue(profileSid != primarySid);
 
         // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        enableSyntheticPassword();
         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
                 mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
 
@@ -231,6 +229,7 @@
     public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
         final String primaryPassword = "testManagedProfileSeparateChallengeMigration-primary";
         final String profilePassword = "testManagedProfileSeparateChallengeMigration-profile";
+        disableSyntheticPassword();
         mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
         mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
@@ -244,8 +243,7 @@
         assertTrue(profileSid != primarySid);
 
         // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        enableSyntheticPassword();
         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
                 mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
@@ -335,7 +333,7 @@
 
     public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration() throws RemoteException {
         final String TOKEN = "some-high-entropy-secure-token";
-        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword();
         long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
         assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
@@ -355,10 +353,10 @@
         final String TOKEN = "some-high-entropy-secure-token";
         final String PASSWORD = "password";
         // Set up pre-SP user password
-        disableSyntheticPassword(PRIMARY_USER_ID);
+        disableSyntheticPassword();
         mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword();
 
         long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
         // Token not activated immediately since user password exists
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
index a599427..520666b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
@@ -27,6 +27,7 @@
 import android.support.test.runner.AndroidJUnit4;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -121,7 +122,6 @@
                 mParentBounds);
     }
 
-
     private void testStackBoundsConfiguration(Integer stackId, Rect parentBounds, Rect bounds,
             Rect expectedConfigBounds) {
         final StackWindowController stackController = stackId != null ?
@@ -140,4 +140,29 @@
         assertTrue((expectedConfigBounds == null && config.appBounds == null)
                 || expectedConfigBounds.equals(config.appBounds));
     }
+
+    /**
+     * Ensures appBounds are considered in {@link Configuration#compareTo(Configuration)}.
+     */
+    @Test
+    public void testConfigurationCompareTo() throws Exception {
+        final Configuration blankConfig = new Configuration();
+
+        final Configuration config1 = new Configuration();
+        config1.appBounds = new Rect(1, 2, 3, 4);
+
+        final Configuration config2 = new Configuration(config1);
+
+        assertEquals(config1.compareTo(config2), 0);
+
+        config2.appBounds.left = 0;
+
+        // Different bounds
+        assertNotEquals(config1.compareTo(config2), 0);
+
+        // No bounds
+        assertEquals(config1.compareTo(blankConfig), -1);
+        assertEquals(blankConfig.compareTo(config1), 1);
+
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index c457cb3..a4e56fc 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -381,6 +381,11 @@
     }
 
     @Override
+    public boolean isInteractive() {
+        return true;
+    }
+
+    @Override
     public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
 
     }
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 9f4fb85..21b11b0 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -392,6 +392,7 @@
         res.videoBytes = stats[2];
         res.imageBytes = stats[3];
         res.appBytes = stats[4];
+        res.obbBytes = stats[5];
         return res;
     }
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 073a17e..25e471c 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -363,19 +363,22 @@
         }
 
         @Override
-        public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+        public void onUidIdle(int uid, boolean disabled) {
             // Ignored
         }
 
         @Override
-        public void onUidGone(int uid, boolean disabled) throws RemoteException {
+        public void onUidGone(int uid, boolean disabled) {
             onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 0);
         }
 
         @Override
-        public void onUidActive(int uid) throws RemoteException {
+        public void onUidActive(int uid) {
             // Ignored
         }
+
+        @Override public void onUidCachedChanged(int uid, boolean cached) {
+        }
     };
 
     @Override
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index 66292f8..ce0dcc3 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -260,12 +260,16 @@
                 }
                 // deviceName is something like: "/dev/bus/usb/001/001"
                 UsbDescriptorParser parser = new UsbDescriptorParser();
+                boolean isInputHeadset = false;
+                boolean isOutputHeadset = false;
                 if (parser.parseDevice(mNewDevice.getDeviceName())) {
-                    Slog.i(TAG, "---- isHeadset[in:" + parser.isInputHeadset()
-                            + " , out:" + parser.isOutputHeadset() + "]");
-                    mUsbAlsaManager.usbDeviceAdded(mNewDevice,
-                            parser.isInputHeadset(), parser.isOutputHeadset());
+                    isInputHeadset = parser.isInputHeadset();
+                    isOutputHeadset = parser.isOutputHeadset();
+                    Slog.i(TAG, "---- isHeadset[in:" + isInputHeadset
+                            + " , out:" + isOutputHeadset + "]");
                 }
+                mUsbAlsaManager.usbDeviceAdded(mNewDevice,
+                        isInputHeadset, isOutputHeadset);
             } else {
                 Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded");
             }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 52b64b6..9c712f4 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1580,7 +1580,7 @@
         sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, "");
         sDefaults.putBoolean(KEY_CSP_ENABLED_BOOL, false);
         sDefaults.putBoolean(KEY_ALLOW_ADDING_APNS_BOOL, true);
-        sDefaults.putStringArray(KEY_READ_ONLY_APN_TYPES_STRING_ARRAY, null);
+        sDefaults.putStringArray(KEY_READ_ONLY_APN_TYPES_STRING_ARRAY, new String[] {"dun"});
         sDefaults.putStringArray(KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
diff --git a/telephony/java/android/telephony/MbmsStreamingManager.java b/telephony/java/android/telephony/MbmsStreamingManager.java
index fb3d5025..8cc447e 100644
--- a/telephony/java/android/telephony/MbmsStreamingManager.java
+++ b/telephony/java/android/telephony/MbmsStreamingManager.java
@@ -142,7 +142,8 @@
      * Starts streaming a requested service, reporting status to the indicated listener.
      * Returns an object used to control that stream. The stream may not be ready for consumption
      * immediately upon return from this method -- wait until the streaming state has been
-     * reported via {@link android.telephony.mbms.StreamingServiceCallback#streamStateUpdated(int)}
+     * reported via
+     * {@link android.telephony.mbms.StreamingServiceCallback#streamStateUpdated(int, int)}
      *
      * May throw an {@link MbmsException} containing any of the following error codes:
      * {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4f78087..b5b32e4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3765,7 +3765,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.iccOpenLogicalChannel(subId, AID, p2);
+                return telephony.iccOpenLogicalChannel(subId, getOpPackageName(), AID, p2);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -6762,4 +6762,3 @@
         return null;
     }
 }
-
diff --git a/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl b/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
index 94c80f4..0952fbe 100755
--- a/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
+++ b/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
@@ -21,7 +21,7 @@
  */
 oneway interface IStreamingServiceCallback {
     void error(int errorCode, String message);
-    void streamStateUpdated(int state);
+    void streamStateUpdated(int state, int reason);
     void mediaDescriptionUpdated();
     void broadcastSignalStrengthUpdated(int signalStrength);
     void streamMethodUpdated(int methodType);
diff --git a/telephony/java/android/telephony/mbms/StreamingService.java b/telephony/java/android/telephony/mbms/StreamingService.java
index 85731a1..475c93a 100644
--- a/telephony/java/android/telephony/mbms/StreamingService.java
+++ b/telephony/java/android/telephony/mbms/StreamingService.java
@@ -16,12 +16,16 @@
 
 package android.telephony.mbms;
 
+import android.annotation.IntDef;
 import android.net.Uri;
 import android.os.DeadObjectException;
 import android.os.RemoteException;
 import android.telephony.mbms.vendor.IMbmsStreamingService;
 import android.util.Log;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * @hide
  */
@@ -30,12 +34,31 @@
 
     /**
      * The state of a stream, reported via {@link StreamingServiceCallback#streamStateUpdated}
+     * @hide
      */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({STATE_STOPPED, STATE_STARTED, STATE_STALLED})
+    public @interface StreamingState {}
     public final static int STATE_STOPPED = 1;
     public final static int STATE_STARTED = 2;
     public final static int STATE_STALLED = 3;
 
     /**
+     * The reason for a stream state change, reported via
+     * {@link StreamingServiceCallback#streamStateUpdated}
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({REASON_BY_USER_REQUEST, REASON_END_OF_SESSION, REASON_FREQUENCY_CONFLICT,
+            REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE})
+    public @interface StreamingStateChangeReason {}
+    public static final int REASON_BY_USER_REQUEST = 1;
+    public static final int REASON_END_OF_SESSION = 2;
+    public static final int REASON_FREQUENCY_CONFLICT = 3;
+    public static final int REASON_OUT_OF_MEMORY = 4;
+    public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5;
+
+    /**
      * The method of transmission currently used for a stream,
      * reported via {@link StreamingServiceCallback#streamMethodUpdated}
      */
diff --git a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
index fdfb188..cab9c23 100644
--- a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
+++ b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
@@ -31,6 +31,7 @@
      */
     public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1;
 
+    @Override
     public void error(int errorCode, String message) {
         // default implementation empty
     }
@@ -41,7 +42,9 @@
      * See {@link StreamingService#STATE_STOPPED}, {@link StreamingService#STATE_STARTED}
      * and {@link StreamingService#STATE_STALLED}.
      */
-    public void streamStateUpdated(int state) {
+    @Override
+    public void streamStateUpdated(@StreamingService.StreamingState int state,
+            @StreamingService.StreamingStateChangeReason int reason) {
         // default implementation empty
     }
 
@@ -55,6 +58,7 @@
      * This may be called when a looping stream hits the end or
      * when parameters have changed to account for time drift.
      */
+    @Override
     public void mediaDescriptionUpdated() {
         // default implementation empty
     }
@@ -69,6 +73,7 @@
      * {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available
      * for this service due to timing, geography or popularity.
      */
+    @Override
     public void broadcastSignalStrengthUpdated(int signalStrength) {
         // default implementation empty
     }
@@ -89,6 +94,7 @@
      * See {@link StreamingService#BROADCAST_METHOD} and
      * {@link StreamingService#UNICAST_METHOD}
      */
+    @Override
     public void streamMethodUpdated(int methodType) {
         // default implementation empty
     }
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
index b6cf628..c97e754 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
@@ -72,7 +72,7 @@
     /**
      * Starts streaming on a particular service. This method may perform asynchronous work. When
      * the middleware is ready to send bits to the frontend, it should inform the app via
-     * {@link IStreamingServiceCallback#streamStateUpdated(int)}.
+     * {@link IStreamingServiceCallback#streamStateUpdated(int, int)}.
      *
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      *
@@ -107,7 +107,7 @@
     /**
      * Stop streaming the stream identified by {@code serviceId}. Notification of the resulting
      * stream state change should be reported to the app via
-     * {@link IStreamingServiceCallback#streamStateUpdated(int)}.
+     * {@link IStreamingServiceCallback#streamStateUpdated(int, int)}.
      *
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      *
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index ab7c5e7..a0e5b7b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -623,11 +623,13 @@
      * Input parameters equivalent to TS 27.007 AT+CCHO command.
      *
      * @param subId The subscription to use.
+     * @param callingPackage the name of the package making the call.
      * @param AID Application id. See ETSI 102.221 and 101.220.
      * @param p2 P2 parameter (described in ISO 7816-4).
      * @return an IccOpenLogicalChannelResponse object.
      */
-    IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID, int p2);
+    IccOpenLogicalChannelResponse iccOpenLogicalChannel(
+            int subId, String callingPackage, String AID, int p2);
 
     /**
      * Closes a previously opened logical channel to the ICC card.
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
index f59a624..fc001e9 100644
--- a/tests/Internal/Android.mk
+++ b/tests/Internal/Android.mk
@@ -10,7 +10,10 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := junit \
+    legacy-android-test \
+    android-support-test \
+    mockito-target-minus-junit4
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/tests/Internal/src/android/app/WallpaperColorsTest.java b/tests/Internal/src/android/app/WallpaperColorsTest.java
new file mode 100644
index 0000000..5bbd82b
--- /dev/null
+++ b/tests/Internal/src/android/app/WallpaperColorsTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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.app;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WallpaperColorsTest {
+
+    @Test
+    public void supportsDarkTextOverrideTest() {
+        final Color color = Color.valueOf(Color.WHITE);
+        // Default should not support dark text!
+        WallpaperColors colors = new WallpaperColors(color, null, null, 0);
+        Assert.assertTrue("Default behavior is not to support dark text",
+                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);
+
+        // Override it
+        colors = new WallpaperColors(color, null, null, WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
+        Assert.assertFalse("Forcing dark text support doesn't work",
+                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);
+    }
+
+    /**
+     * Sanity check to guarantee that white supports dark text and black doesn't
+     */
+    @Test
+    public void colorHintsTest() {
+        Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(image);
+
+        canvas.drawColor(Color.WHITE);
+        int hints = WallpaperColors.fromBitmap(image).getColorHints();
+        boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        Assert.assertTrue("White surface should support dark text", supportsDarkText);
+        Assert.assertFalse("White surface shouldn't support dark theme", supportsDarkTheme);
+
+        canvas.drawColor(Color.BLACK);
+        hints = WallpaperColors.fromBitmap(image).getColorHints();
+        supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        Assert.assertFalse("Black surface shouldn't support dark text", supportsDarkText);
+        Assert.assertTrue("Black surface should support dark theme", supportsDarkTheme);
+
+        Paint paint = new Paint();
+        paint.setStyle(Paint.Style.FILL);
+        paint.setColor(Color.BLACK);
+        canvas.drawColor(Color.WHITE);
+        canvas.drawRect(0, 0, 8, 8, paint);
+        supportsDarkText = (WallpaperColors.fromBitmap(image)
+                .getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        Assert.assertFalse("Light surface shouldn't support dark text "
+                + "when it contains dark pixels", supportsDarkText);
+    }
+}
diff --git a/packages/SystemUI/colorextraction/tests/src/com/google/android/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
similarity index 92%
rename from packages/SystemUI/colorextraction/tests/src/com/google/android/colorextraction/ColorExtractorTest.java
rename to tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index b5f4a8c..7182147 100644
--- a/packages/SystemUI/colorextraction/tests/src/com/google/android/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -13,16 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License
  */
-package com.google.android.colorextraction;
+package com.android.internal.colorextraction;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.Color;
@@ -30,9 +29,10 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.google.android.colorextraction.ColorExtractor.GradientColors;
-import com.google.android.colorextraction.types.ExtractionType;
-import com.google.android.colorextraction.types.Tonal;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/SystemUI/colorextraction/tests/src/com/google/android/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
similarity index 83%
rename from packages/SystemUI/colorextraction/tests/src/com/google/android/colorextraction/types/TonalTest.java
rename to tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
index 404076c..1e3e8e9 100644
--- a/packages/SystemUI/colorextraction/tests/src/com/google/android/colorextraction/types/TonalTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License
  */
-package com.google.android.colorextraction.types;
+package com.android.internal.colorextraction.types;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -22,19 +22,15 @@
 import android.graphics.Color;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.support.v4.graphics.ColorUtils;
-import android.util.Pair;
 import android.util.Range;
 
-import com.google.android.colorextraction.ColorExtractor;
-import com.google.android.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.graphics.ColorUtils;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 
 /**
  * Tests tonal palette generation.
@@ -71,9 +67,8 @@
     public void colorRange_excludeBlacklistedColor() {
         // Creating a WallpaperColors object that contains *only* blacklisted colors
         float[] hsl = Tonal.BLACKLISTED_COLORS[0].getCenter();
-        ArrayList<Pair<Color, Integer>> blacklistedColorList = new ArrayList<>();
-        blacklistedColorList.add(new Pair<>(Color.valueOf(ColorUtils.HSLToColor(hsl)), 1));
-        WallpaperColors colors = new WallpaperColors(blacklistedColorList);
+        WallpaperColors colors = new WallpaperColors(Color.valueOf(ColorUtils.HSLToColor(hsl)),
+                null, null, 0);
 
         // Make sure that palette generation will fail
         Tonal tonal = new Tonal();
diff --git a/tests/MusicBrowserDemo/Android.mk b/tests/MusicBrowserDemo/Android.mk
deleted file mode 100644
index 207774b..0000000
--- a/tests/MusicBrowserDemo/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2014 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := MusicBrowserDemo
-#LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-v4 \
-    android-support-v7-appcompat
-
-LOCAL_RESOURCE_DIR := \
-        $(LOCAL_PATH)/res \
-        frameworks/support/v7/appcompat/res
-LOCAL_PROGUARD_ENABLED := disabled
-#LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-LOCAL_AAPT_FLAGS := \
-        --auto-add-overlay \
-        --extra-packages android.support.v7.appcompat
-include $(BUILD_PACKAGE)
diff --git a/tests/MusicBrowserDemo/AndroidManifest.xml b/tests/MusicBrowserDemo/AndroidManifest.xml
deleted file mode 100644
index d2acfe2..0000000
--- a/tests/MusicBrowserDemo/AndroidManifest.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 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.
-  -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.android.musicbrowserdemo"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk
-        android:minSdkVersion="9"
-        android:targetSdkVersion="19" />
-
-    <application
-        android:allowBackup="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:theme="@style/AppTheme"
-        >
-
-        <activity
-            android:name="com.example.android.musicbrowserdemo.MainActivity"
-            android:label="@string/app_name"
-            >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-    </application>
-
-</manifest>
diff --git a/tests/MusicBrowserDemo/res/drawable-hdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 47d6854..0000000
--- a/tests/MusicBrowserDemo/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/drawable-mdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 01b53fd..0000000
--- a/tests/MusicBrowserDemo/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/drawable-xhdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index af762f2..0000000
--- a/tests/MusicBrowserDemo/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/drawable-xxhdpi/ic_launcher.png b/tests/MusicBrowserDemo/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644
index eef47aa..0000000
--- a/tests/MusicBrowserDemo/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicBrowserDemo/res/values/strings.xml b/tests/MusicBrowserDemo/res/values/strings.xml
deleted file mode 100644
index 858f278f..0000000
--- a/tests/MusicBrowserDemo/res/values/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<resources>
-
-    <string name="app_name">Music Browser</string>
-
-</resources>
diff --git a/tests/MusicBrowserDemo/res/values/styles.xml b/tests/MusicBrowserDemo/res/values/styles.xml
deleted file mode 100644
index b83662d..0000000
--- a/tests/MusicBrowserDemo/res/values/styles.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-
-</resources>
diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java
deleted file mode 100644
index 4e18ce9..0000000
--- a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2014 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.example.android.musicbrowserdemo;
-
-import android.content.Context;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.service.media.MediaBrowserService;
-import android.os.Bundle;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.app.ListFragment;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-// TODO: Include an icon.
-
-public class AppListFragment extends ListFragment {
-
-    private Adapter mAdapter;
-    private List<Item> mItems;
-
-    public AppListFragment() {
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        mAdapter = new Adapter();
-        setListAdapter(mAdapter);
-    }
-
-    @Override
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        final Item item = mItems.get(position);
-
-        Log.i("AppListFragment", "Item clicked: " + position + " -- " + item.component);
-
-        final BrowserListFragment fragment = new BrowserListFragment();
-
-        final Bundle args = new Bundle();
-        args.putParcelable(BrowserListFragment.ARG_COMPONENT, item.component);
-        fragment.setArguments(args);
-
-        getFragmentManager().beginTransaction()
-                .replace(android.R.id.content, fragment)
-                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
-                .addToBackStack(null)
-                .commit();
-    }
-
-    private static class Item {
-        final String label;
-        final ComponentName component;
-
-        Item(String l, ComponentName c) {
-            this.label = l;
-            this.component = c;
-        }
-    }
-
-    private class Adapter extends BaseAdapter {
-        private final LayoutInflater mInflater;
-
-        Adapter() {
-            super();
-
-            final Context context = getActivity();
-            mInflater = LayoutInflater.from(context);
-
-            // Load the data
-            final PackageManager pm = context.getPackageManager();
-            final Intent intent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
-            final List<ResolveInfo> list = pm.queryIntentServices(intent, 0);
-            final int N = list.size();
-            mItems = new ArrayList(N);
-            for (int i=0; i<N; i++) {
-                final ResolveInfo ri = list.get(i);
-                mItems.add(new Item(ri.loadLabel(pm).toString(), new ComponentName(
-                            ri.serviceInfo.applicationInfo.packageName,
-                            ri.serviceInfo.name)));
-            }
-        }
-
-        @Override
-        public int getCount() {
-            return mItems.size();
-        }
-
-        @Override
-        public Item getItem(int position) {
-            return mItems.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public int getItemViewType(int position) {
-            return 1;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
-            }
-
-            final TextView tv = (TextView)convertView;
-            final Item item = mItems.get(position);
-            tv.setText(item.label);
-
-            return convertView;
-        }
-
-        @Override
-        public int getViewTypeCount() {
-            return 1;
-        }
-    }
-}
-
-
diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java
deleted file mode 100644
index 8cc9b97..0000000
--- a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2014 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.example.android.musicbrowserdemo;
-
-import android.content.Context;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.media.browse.MediaBrowser;
-import android.service.media.MediaBrowserService;
-import android.os.Bundle;
-import android.net.Uri;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.app.ListFragment;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class BrowserListFragment extends ListFragment {
-    private static final String TAG = "BrowserListFragment";
-
-    // Hints
-    public static final String HINT_DISPLAY = "com.example.android.musicbrowserdemo.DISPLAY";
-
-    // For args
-    public static final String ARG_COMPONENT = "component";
-    public static final String ARG_ID = "uri";
-
-    private Adapter mAdapter;
-    private List<Item> mItems = new ArrayList();
-    private ComponentName mComponent;
-    private String mNodeId;
-    private MediaBrowser mBrowser;
-
-    private static class Item {
-        final MediaBrowser.MediaItem media;
-
-        Item(MediaBrowser.MediaItem m) {
-            this.media = m;
-        }
-    }
-
-    public BrowserListFragment() {
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        Log.d(TAG, "onActivityCreated -- " + hashCode());
-        mAdapter = new Adapter();
-        setListAdapter(mAdapter);
-
-        // Get our arguments
-        final Bundle args = getArguments();
-        mComponent = args.getParcelable(ARG_COMPONENT);
-        mNodeId = args.getString(ARG_ID);
-
-        // A hint about who we are, so the service can customize the results if it wants to.
-        final Bundle rootHints = new Bundle();
-        rootHints.putBoolean(HINT_DISPLAY, true);
-
-        mBrowser = new MediaBrowser(getActivity(), mComponent, mConnectionCallbacks, rootHints);
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        mBrowser.connect();
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        mBrowser.disconnect();
-    }
-
-    @Override
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        final Item item = mItems.get(position);
-
-        Log.i("BrowserListFragment", "Item clicked: " + position + " -- "
-                + mAdapter.getItem(position).media.getDescription().getIconUri());
-
-        final BrowserListFragment fragment = new BrowserListFragment();
-
-        final Bundle args = new Bundle();
-        args.putParcelable(BrowserListFragment.ARG_COMPONENT, mComponent);
-        args.putParcelable(BrowserListFragment.ARG_ID, item.media.getDescription().getIconUri());
-        fragment.setArguments(args);
-
-        getFragmentManager().beginTransaction()
-                .replace(android.R.id.content, fragment)
-                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
-                .addToBackStack(null)
-                .commit();
-
-    }
-
-    final MediaBrowser.ConnectionCallback mConnectionCallbacks
-            = new MediaBrowser.ConnectionCallback() {
-        @Override
-        public void onConnected() {
-            Log.d(TAG, "mConnectionCallbacks.onConnected");
-            if (mNodeId == null) {
-                mNodeId = mBrowser.getRoot();
-            }
-            mBrowser.subscribe(mNodeId, new MediaBrowser.SubscriptionCallback() {
-                    @Override
-                public void onChildrenLoaded(String parentId,
-                            List<MediaBrowser.MediaItem> children) {
-                    Log.d(TAG, "onChildrenLoaded parentId=" + parentId
-                                + " children= " + children);
-                        mItems.clear();
-                        final int N = children.size();
-                        for (int i=0; i<N; i++) {
-                            mItems.add(new Item(children.get(i)));
-                        }
-                        mAdapter.notifyDataSetChanged();
-                    }
-
-                    @Override
-                public void onError(String parentId) {
-                    Log.d(TAG, "onError parentId=" + parentId);
-                    }
-                });
-        }
-
-        @Override
-        public void onConnectionSuspended() {
-            Log.d(TAG, "mConnectionCallbacks.onConnectionSuspended");
-        }
-
-        @Override
-        public void onConnectionFailed() {
-            Log.d(TAG, "mConnectionCallbacks.onConnectionFailed");
-        }
-    };
-
-    private class Adapter extends BaseAdapter {
-        private final LayoutInflater mInflater;
-
-        Adapter() {
-            super();
-
-            final Context context = getActivity();
-            mInflater = LayoutInflater.from(context);
-        }
-
-        @Override
-        public int getCount() {
-            return mItems.size();
-        }
-
-        @Override
-        public Item getItem(int position) {
-            return mItems.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public int getItemViewType(int position) {
-            return 1;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
-            }
-
-            final TextView tv = (TextView)convertView;
-            final Item item = mItems.get(position);
-            tv.setText(item.media.getDescription().getTitle());
-
-            return convertView;
-        }
-
-        @Override
-        public int getViewTypeCount() {
-            return 1;
-        }
-    }
-}
-
-
diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java
deleted file mode 100644
index 4c28234..0000000
--- a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2014 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.example.android.musicbrowserdemo;
-
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-/**
- * Main activity class.
- */
-public class MainActivity extends FragmentActivity {
-
-    private static final String BROWSER_FRAGMENT_TAG = "browser";
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        Log.d("MainActivity", "-------------------------------------------------------");
-
-        // If we are starting afresh, start at the app list.
-        final FragmentManager fm = getSupportFragmentManager();
-        if (fm.findFragmentById(android.R.id.content) == null) {
-            fm.beginTransaction().add(android.R.id.content, new AppListFragment()).commit();
-        }
-    }
-}
-
diff --git a/tests/MusicServiceDemo/Android.mk b/tests/MusicServiceDemo/Android.mk
deleted file mode 100644
index feef67a..0000000
--- a/tests/MusicServiceDemo/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2013 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := MusicServiceDemo
-#LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-v4 \
-    android-support-v7-appcompat
-
-LOCAL_RESOURCE_DIR := \
-        $(LOCAL_PATH)/res \
-        frameworks/support/v7/appcompat/res
-LOCAL_PROGUARD_ENABLED := disabled
-#LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-LOCAL_AAPT_FLAGS := \
-        --auto-add-overlay \
-        --extra-packages android.support.v7.appcompat
-include $(BUILD_PACKAGE)
diff --git a/tests/MusicServiceDemo/AndroidManifest.xml b/tests/MusicServiceDemo/AndroidManifest.xml
deleted file mode 100644
index e00e2e2..0000000
--- a/tests/MusicServiceDemo/AndroidManifest.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 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.
-  -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.android.musicservicedemo"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-
-    <uses-sdk
-        android:minSdkVersion="9"
-        android:targetSdkVersion="19" />
-
-    <application
-        android:allowBackup="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:theme="@style/AppTheme"
-        >
-
-        <activity
-            android:name="com.example.android.automotive.musicplayer.MainActivity"
-            android:label="@string/app_name" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-        <service
-            android:name=".BrowserService"
-            android:exported="true"
-            >
-            <intent-filter>
-                <action android:name="android.media.browse.MediaBrowserService" />
-            </intent-filter>
-        </service>
-    </application>
-
-</manifest>
diff --git a/tests/MusicServiceDemo/proguard-project.txt b/tests/MusicServiceDemo/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/tests/MusicServiceDemo/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
diff --git a/tests/MusicServiceDemo/res/drawable-hdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 47d6854..0000000
--- a/tests/MusicServiceDemo/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-mdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 01b53fd..0000000
--- a/tests/MusicServiceDemo/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-xhdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index af762f2..0000000
--- a/tests/MusicServiceDemo/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-xxhdpi/ic_launcher.png b/tests/MusicServiceDemo/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644
index eef47aa..0000000
--- a/tests/MusicServiceDemo/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicServiceDemo/res/drawable-xxhdpi/thumbsup.png b/tests/MusicServiceDemo/res/drawable-xxhdpi/thumbsup.png
deleted file mode 100644
index ea98c95..0000000
--- a/tests/MusicServiceDemo/res/drawable-xxhdpi/thumbsup.png
+++ /dev/null
Binary files differ
diff --git a/tests/MusicServiceDemo/res/layout/activity_main.xml b/tests/MusicServiceDemo/res/layout/activity_main.xml
deleted file mode 100644
index 71753e3..0000000
--- a/tests/MusicServiceDemo/res/layout/activity_main.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 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.
-  -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context="com.example.android.automotive.musicplayer.MainActivity"
-    tools:ignore="MergeRootFrame" />
diff --git a/tests/MusicServiceDemo/res/layout/fragment_main.xml b/tests/MusicServiceDemo/res/layout/fragment_main.xml
deleted file mode 100644
index 8796e86..0000000
--- a/tests/MusicServiceDemo/res/layout/fragment_main.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 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.
-  -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:paddingBottom="@dimen/activity_vertical_margin"
-    android:paddingLeft="@dimen/activity_horizontal_margin"
-    android:paddingRight="@dimen/activity_horizontal_margin"
-    android:paddingTop="@dimen/activity_vertical_margin"
-    tools:context="com.example.android.automotive.musicplayer.MainActivity$PlaceholderFragment" >
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/app_name" />
-
-</RelativeLayout>
diff --git a/tests/MusicServiceDemo/res/values/colors.xml b/tests/MusicServiceDemo/res/values/colors.xml
deleted file mode 100644
index 44dd05d..0000000
--- a/tests/MusicServiceDemo/res/values/colors.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <color name="yellow">#ffffff00</color>
-    <color name="green">#ff00ff00</color>
-    <color name="blue">#ff0000ff</color>
-    <color name="red">#ffff0000</color>
-</resources>
diff --git a/tests/MusicServiceDemo/res/values/dimens.xml b/tests/MusicServiceDemo/res/values/dimens.xml
deleted file mode 100644
index 9f63ef2..0000000
--- a/tests/MusicServiceDemo/res/values/dimens.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<resources>
-
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-
-</resources>
diff --git a/tests/MusicServiceDemo/res/values/strings.xml b/tests/MusicServiceDemo/res/values/strings.xml
deleted file mode 100644
index 14c0171..0000000
--- a/tests/MusicServiceDemo/res/values/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<resources>
-
-    <string name="app_name">Music Service Demo</string>
-    <string name="action_settings">Settings</string>
-    <string name="thumbs_up">Thumbs Up</string>
-    <string name="music_error">No music found</string>
-    <string name="now_playing">Now Playing</string>
-
-</resources>
diff --git a/tests/MusicServiceDemo/res/values/styles.xml b/tests/MusicServiceDemo/res/values/styles.xml
deleted file mode 100644
index b83662d..0000000
--- a/tests/MusicServiceDemo/res/values/styles.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2014 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-
-</resources>
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java
deleted file mode 100644
index 4e2e47e..0000000
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/BrowserService.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All Rights Reserved.
- *
- * 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.example.android.musicservicedemo;
-
-import android.app.SearchManager;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.UriMatcher;
-import android.content.res.Resources.NotFoundException;
-import android.database.MatrixCursor;
-import android.graphics.Bitmap;
-import android.media.AudioManager;
-import android.media.MediaDescription;
-import android.media.MediaPlayer;
-import android.media.MediaPlayer.OnCompletionListener;
-import android.media.MediaPlayer.OnErrorListener;
-import android.media.MediaPlayer.OnPreparedListener;
-import android.media.browse.MediaBrowser;
-import android.service.media.MediaBrowserService;
-import android.service.media.MediaBrowserService.BrowserRoot;
-import android.media.session.MediaSession;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.WifiLock;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.example.android.musicservicedemo.browser.MusicProvider;
-import com.example.android.musicservicedemo.browser.MusicProviderTask;
-import com.example.android.musicservicedemo.browser.MusicProviderTaskListener;
-import com.example.android.musicservicedemo.browser.MusicTrack;
-
-import org.json.JSONException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Service that implements MediaBrowserService and returns our menu hierarchy.
- */
-public class BrowserService extends MediaBrowserService {
-    private static final String TAG = "BrowserService";
-
-    // URI paths for browsing music
-    public static final String BROWSE_ROOT_BASE_PATH = "browse";
-    public static final String NOW_PLAYING_PATH = "now_playing";
-    public static final String PIANO_BASE_PATH = "piano";
-    public static final String VOICE_BASE_PATH = "voice";
-
-    // Content URIs
-    public static final String AUTHORITY = "com.example.android.automotive.musicplayer";
-    public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
-    public static final Uri BROWSE_URI = Uri.withAppendedPath(BASE_URI, BROWSE_ROOT_BASE_PATH);
-
-    // URI matcher constants for browsing paths
-    public static final int BROWSE_ROOT = 1;
-    public static final int NOW_PLAYING = 2;
-    public static final int PIANO = 3;
-    public static final int VOICE = 4;
-
-    // Map the the URI paths with the URI matcher constants
-    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-    static {
-        sUriMatcher.addURI(AUTHORITY, BROWSE_ROOT_BASE_PATH, BROWSE_ROOT);
-        sUriMatcher.addURI(AUTHORITY, NOW_PLAYING_PATH, NOW_PLAYING);
-        sUriMatcher.addURI(AUTHORITY, PIANO_BASE_PATH, PIANO);
-        sUriMatcher.addURI(AUTHORITY, VOICE_BASE_PATH, VOICE);
-    }
-
-    // Media metadata that will be provided for a media container
-    public static final String[] MEDIA_CONTAINER_PROJECTION = {
-            "uri",
-            "title",
-            "subtitle",
-            "image_uri",
-            "supported_actions"
-    };
-
-    // MusicProvider will download the music catalog
-    private MusicProvider mMusicProvider;
-
-    private MediaSession mSession;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-
-        mSession = new MediaSession(this, "com.example.android.musicservicedemo.BrowserService");
-        setSessionToken(mSession.getSessionToken());
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-    }
-
-    @Override
-    public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
-        return new BrowserRoot(BROWSE_URI.toString(), null);
-    }
-
-    @Override
-    public void onLoadChildren(final String parentId,
-            final Result<List<MediaBrowser.MediaItem>> result) {
-        new Handler().postDelayed(new Runnable() {
-                public void run() {
-                    final ArrayList<MediaBrowser.MediaItem> list = new ArrayList();
-
-                    for (int i=0; i<10; i++) {
-                        MediaDescription.Builder bob = new MediaDescription.Builder();
-                        bob.setTitle("Title " + i);
-                        bob.setSubtitle("Summary " + i);
-                        bob.setMediaId(Uri.withAppendedPath(BASE_URI,
-                                Integer.toString(i)).toString());
-                        list.add(new MediaBrowser.MediaItem(bob.build(),
-                                MediaBrowser.MediaItem.FLAG_BROWSABLE));
-                    }
-
-                    result.sendResult(list);
-                }
-            }, 2000);
-        result.detach();
-    }
-
-    /*
-    @Override
-    public void query(final Query query, final IMetadataResultHandler metadataResultHandler,
-            final IErrorHandler errorHandler)
-            throws RemoteException {
-        Log.d(TAG, "query: " + query);
-        Utils.checkNotNull(query);
-        Utils.checkNotNull(metadataResultHandler);
-        Utils.checkNotNull(errorHandler);
-
-        // Handle async response
-        new Thread(new Runnable() {
-            public void run() {
-                try {
-                    // Pre-load the list of music
-                    List<MusicTrack> musicTracks = getMusicList();
-                    if (musicTracks == null) {
-                        notifyListenersOnPlaybackStateUpdate(getCurrentPlaybackState());
-                        errorHandler.onError(new Error(Error.UNKNOWN,
-                                getString(R.string.music_error)));
-                        return;
-                    }
-
-                    final Uri uri = query.getUri();
-                    int match = sUriMatcher.match(uri);
-                    Log.d(TAG, "Queried: " + uri + "; match: " + match);
-                    switch (match) {
-                        case BROWSE_ROOT:
-                        {
-                            Log.d(TAG, "Browse_root");
-
-                            try {
-                                MatrixCursor matrixCursor = mMusicProvider
-                                        .getRootContainerCurser();
-                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
-                                        matrixCursor, null);
-
-                                Log.d(TAG, "on metadata response called " + holder.getCount());
-                                metadataResultHandler.onMetadataResponse(holder);
-                            } catch (RemoteException e) {
-                                Log.w(TAG, "Error delivering metadata in the callback.", e);
-                            }
-                            break;
-                        }
-                        case NOW_PLAYING:
-                        {
-                            try {
-                                Log.d(TAG, "query NOW_PLAYING");
-                                MatrixCursor matrixCursor = mMusicProvider
-                                        .getRootItemCursor(
-                                        PIANO);
-                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
-                                        matrixCursor, null);
-                                Log.d(TAG, "on metadata response called " + holder.getCount());
-                                metadataResultHandler.onMetadataResponse(holder);
-                            } catch (RemoteException e) {
-                                Log.w(TAG, "Error querying NOW_PLAYING");
-                            }
-                            break;
-                        }
-                        case PIANO:
-                        {
-                            try {
-                                Log.d(TAG, "query PIANO");
-                                MatrixCursor matrixCursor = mMusicProvider
-                                        .getRootItemCursor(
-                                        PIANO);
-                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
-                                        matrixCursor, null);
-                                Log.d(TAG, "on metadata response called " + holder.getCount());
-                                metadataResultHandler.onMetadataResponse(holder);
-                            } catch (RemoteException e) {
-                                Log.w(TAG, "Error querying PIANO");
-                            }
-                            break;
-                        }
-                        case VOICE:
-                        {
-                            try {
-                                Log.d(TAG, "query VOICE");
-                                MatrixCursor matrixCursor = mMusicProvider
-                                        .getRootItemCursor(
-                                        VOICE);
-                                DataHolder holder = new DataHolder(MEDIA_CONTAINER_PROJECTION,
-                                        matrixCursor, null);
-                                Log.d(TAG, "on metadata response called " + holder.getCount());
-                                metadataResultHandler.onMetadataResponse(holder);
-                            } catch (RemoteException e) {
-                                Log.w(TAG, "Error querying VOICE");
-                            }
-                            break;
-                        }
-                        default:
-                        {
-                            Log.w(TAG, "Skipping unmatched URI: " + uri);
-                        }
-                    }
-                } catch (NotFoundException e) {
-                    Log.e(TAG, "::run:", e);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "::run:", e);
-                }
-            } // end run
-        }).start();
-    }
-
-    */
-}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java
deleted file mode 100644
index 99d44e6..0000000
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2014 Google Inc. All Rights Reserved.
- *
- * 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.example.android.musicservicedemo;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v7.app.AppCompatActivity;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.example.android.musicservicedemo.R;
-
-// TODO Local UI
-
-/**
- * Main activity of the app.
- */
-public class MainActivity extends AppCompatActivity {
-
-    private static final String LOG = "MainActivity";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_main);
-
-        if (savedInstanceState == null) {
-            getSupportFragmentManager().beginTransaction()
-                    .add(R.id.container, new PlaceholderFragment())
-                    .commit();
-        }
-
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
-     */
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-
-        // Inflate the menu; this adds items to the action bar if it is present.
-        //getMenuInflater().inflate(R.menu.main, menu);
-        return true;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
-     */
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-        int id = item.getItemId();
-        // if (id == R.id.action_settings) {
-        // return true;
-        // }
-        return super.onOptionsItemSelected(item);
-    }
-
-    /**
-     * A placeholder fragment containing a simple view.
-     */
-    public static class PlaceholderFragment extends Fragment {
-
-        public PlaceholderFragment() {
-        }
-
-        /*
-         * (non-Javadoc)
-         * @see
-         * android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater
-         * , android.view.ViewGroup, android.os.Bundle)
-         */
-        @Override
-        public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                Bundle savedInstanceState) {
-            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
-            return rootView;
-        }
-    }
-
-}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/Utils.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/Utils.java
deleted file mode 100644
index 3589761..0000000
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/Utils.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All Rights Reserved.
- *
- * 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.example.android.musicservicedemo;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-public class Utils {
-
-    private static final String TAG = "Utils";
-
-    /**
-     * Utility method to check that parameters are not null
-     *
-     * @param object
-     */
-    public static final void checkNotNull(Object object) {
-        if (object == null) {
-            throw new NullPointerException();
-        }
-    }
-
-    /**
-     * Utility to download a bitmap
-     *
-     * @param source
-     * @return
-     */
-    public static Bitmap getBitmapFromURL(String source) {
-        try {
-            URL url = new URL(source);
-            HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
-            httpConnection.setDoInput(true);
-            httpConnection.connect();
-            InputStream inputStream = httpConnection.getInputStream();
-            return BitmapFactory.decodeStream(inputStream);
-        } catch (IOException e) {
-            Log.e(TAG, "getBitmapFromUrl: " + source, e);
-        }
-        return null;
-    }
-
-    /**
-     * Utility method to wrap an index
-     *
-     * @param i
-     * @param size
-     * @return
-     */
-    public static int wrapIndex(int i, int size) {
-        int m = i % size;
-        if (m < 0) { // java modulus can be negative
-            m += size;
-        }
-        return m;
-    }
-}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProvider.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProvider.java
deleted file mode 100644
index 15038d7..0000000
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProvider.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All Rights Reserved.
- *
- * 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.example.android.musicservicedemo.browser;
-
-import android.database.MatrixCursor;
-import android.media.session.PlaybackState;
-import android.net.Uri;
-import android.util.Log;
-
-import com.example.android.musicservicedemo.BrowserService;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility class to get a list of MusicTrack's based on a server-side JSON
- * configuration.
- */
-public class MusicProvider {
-
-    private static final String TAG = "MusicProvider";
-
-    private static final String MUSIC_URL = "http://storage.googleapis.com/automotive-media/music.json";
-
-    private static String MUSIC = "music";
-    private static String TITLE = "title";
-    private static String ALBUM = "album";
-    private static String ARTIST = "artist";
-    private static String GENRE = "genre";
-    private static String SOURCE = "source";
-    private static String IMAGE = "image";
-    private static String TRACK_NUMBER = "trackNumber";
-    private static String TOTAL_TRACK_COUNT = "totalTrackCount";
-    private static String DURATION = "duration";
-
-    // Cache for music track data
-    private static List<MusicTrack> mMusicList;
-
-    /**
-     * Get the cached list of music tracks
-     *
-     * @return
-     * @throws JSONException
-     */
-    public List<MusicTrack> getMedia() throws JSONException {
-        if (null != mMusicList && mMusicList.size() > 0) {
-            return mMusicList;
-        }
-        return null;
-    }
-
-    /**
-     * Get the list of music tracks from a server and return the list of
-     * MusicTrack objects.
-     *
-     * @return
-     * @throws JSONException
-     */
-    public List<MusicTrack> retreiveMedia() throws JSONException {
-        if (null != mMusicList) {
-            return mMusicList;
-        }
-        int slashPos = MUSIC_URL.lastIndexOf('/');
-        String path = MUSIC_URL.substring(0, slashPos + 1);
-        JSONObject jsonObj = parseUrl(MUSIC_URL);
-
-        try {
-            JSONArray videos = jsonObj.getJSONArray(MUSIC);
-            if (null != videos) {
-                mMusicList = new ArrayList<MusicTrack>();
-                for (int j = 0; j < videos.length(); j++) {
-                    JSONObject music = videos.getJSONObject(j);
-                    String title = music.getString(TITLE);
-                    String album = music.getString(ALBUM);
-                    String artist = music.getString(ARTIST);
-                    String genre = music.getString(GENRE);
-                    String source = music.getString(SOURCE);
-                    // Media is stored relative to JSON file
-                    if (!source.startsWith("http")) {
-                        source = path + source;
-                    }
-                    String image = music.getString(IMAGE);
-                    if (!image.startsWith("http")) {
-                        image = path + image;
-                    }
-                    int trackNumber = music.getInt(TRACK_NUMBER);
-                    int totalTrackCount = music.getInt(TOTAL_TRACK_COUNT);
-                    int duration = music.getInt(DURATION) * 1000; // ms
-
-                    mMusicList.add(new MusicTrack(title, album, artist, genre, source,
-                            image, trackNumber, totalTrackCount, duration));
-                }
-            }
-        } catch (NullPointerException e) {
-            Log.e(TAG, "retreiveMedia", e);
-        }
-        return mMusicList;
-    }
-
-    /**
-     * Download a JSON file from a server, parse the content and return the JSON
-     * object.
-     *
-     * @param urlString
-     * @return
-     */
-    private JSONObject parseUrl(String urlString) {
-        InputStream is = null;
-        try {
-            java.net.URL url = new java.net.URL(urlString);
-            URLConnection urlConnection = url.openConnection();
-            is = new BufferedInputStream(urlConnection.getInputStream());
-            BufferedReader reader = new BufferedReader(new InputStreamReader(
-                    urlConnection.getInputStream(), "iso-8859-1"), 8);
-            StringBuilder sb = new StringBuilder();
-            String line = null;
-            while ((line = reader.readLine()) != null) {
-                sb.append(line);
-            }
-            return new JSONObject(sb.toString());
-        } catch (Exception e) {
-            Log.d(TAG, "Failed to parse the json for media list", e);
-            return null;
-        } finally {
-            if (null != is) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    // ignore
-                }
-            }
-        }
-    }
-
-    public MatrixCursor getRootContainerCurser() {
-        MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
-        Uri.Builder pianoBuilder = new Uri.Builder();
-        pianoBuilder.authority(BrowserService.AUTHORITY);
-        pianoBuilder.appendPath(BrowserService.PIANO_BASE_PATH);
-        matrixCursor.addRow(new Object[] {
-                pianoBuilder.build(),
-                BrowserService.PIANO_BASE_PATH,
-                "subtitle",
-                null,
-                0
-        });
-
-        Uri.Builder voiceBuilder = new Uri.Builder();
-        voiceBuilder.authority(BrowserService.AUTHORITY);
-        voiceBuilder.appendPath(BrowserService.VOICE_BASE_PATH);
-        matrixCursor.addRow(new Object[] {
-                voiceBuilder.build(),
-                BrowserService.VOICE_BASE_PATH,
-                "subtitle",
-                null,
-                0
-        });
-        return matrixCursor;
-    }
-
-    public MatrixCursor getRootItemCursor(int type) {
-        if (type == BrowserService.NOW_PLAYING) {
-            MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
-
-            try {
-                // Just return all of the tracks for now
-                List<MusicTrack> musicTracks = retreiveMedia();
-                for (MusicTrack musicTrack : musicTracks) {
-                    Uri.Builder builder = new Uri.Builder();
-                    builder.authority(BrowserService.AUTHORITY);
-                    builder.appendPath(BrowserService.NOW_PLAYING_PATH);
-                    builder.appendPath(musicTrack.getTitle());
-                    matrixCursor.addRow(new Object[] {
-                            builder.build(),
-                            musicTrack.getTitle(),
-                            musicTrack.getArtist(),
-                            musicTrack.getImage(),
-                            PlaybackState.ACTION_PLAY
-                    });
-                    Log.d(TAG, "Uri " + builder.build());
-                }
-            } catch (JSONException e) {
-                Log.e(TAG, "::getRootItemCursor:", e);
-            }
-
-            Log.d(TAG, "cursor: " + matrixCursor.getCount());
-            return matrixCursor;
-        } else if (type == BrowserService.PIANO) {
-            MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
-
-            try {
-                List<MusicTrack> musicTracks = retreiveMedia();
-                for (MusicTrack musicTrack : musicTracks) {
-                    Uri.Builder builder = new Uri.Builder();
-                    builder.authority(BrowserService.AUTHORITY);
-                    builder.appendPath(BrowserService.PIANO_BASE_PATH);
-                    builder.appendPath(musicTrack.getTitle());
-                    matrixCursor.addRow(new Object[] {
-                            builder.build(),
-                            musicTrack.getTitle(),
-                            musicTrack.getArtist(),
-                            musicTrack.getImage(),
-                            PlaybackState.ACTION_PLAY
-                    });
-                    Log.d(TAG, "Uri " + builder.build());
-                }
-            } catch (JSONException e) {
-                Log.e(TAG, "::getRootItemCursor:", e);
-            }
-
-            Log.d(TAG, "cursor: " + matrixCursor.getCount());
-            return matrixCursor;
-        } else if (type == BrowserService.VOICE) {
-            MatrixCursor matrixCursor = new MatrixCursor(BrowserService.MEDIA_CONTAINER_PROJECTION);
-
-            try {
-                List<MusicTrack> musicTracks = retreiveMedia();
-                for (MusicTrack musicTrack : musicTracks) {
-                    Uri.Builder builder = new Uri.Builder();
-                    builder.authority(BrowserService.AUTHORITY);
-                    builder.appendPath(BrowserService.VOICE_BASE_PATH);
-                    builder.appendPath(musicTrack.getTitle());
-                    matrixCursor.addRow(new Object[] {
-                            builder.build(),
-                            musicTrack.getTitle(),
-                            musicTrack.getArtist(),
-                            musicTrack.getImage(),
-                            PlaybackState.ACTION_PLAY
-                    });
-                    Log.d(TAG, "Uri " + builder.build());
-                }
-            } catch (JSONException e) {
-                Log.e(TAG, "::getRootItemCursor:", e);
-            }
-
-            Log.d(TAG, "cursor: " + matrixCursor.getCount());
-            return matrixCursor;
-
-        }
-        return null;
-    }
-}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTask.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTask.java
deleted file mode 100644
index ffda110..0000000
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTask.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*  
- * Copyright (C) 2014 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.example.android.musicservicedemo.browser;
-
-import android.os.AsyncTask;
-import android.util.Log;
-
-import org.json.JSONException;
-
-/**
- * Asynchronous task to retrieve the music data using MusicProvider.
- */
-public class MusicProviderTask extends AsyncTask<Void, Void, Void> {
-
-    private static final String TAG = "MusicProviderTask";
-
-    MusicProvider mMusicProvider;
-    MusicProviderTaskListener mMusicProviderTaskListener;
-
-    /**
-     * Initialize the task with the provider to download the music data and the
-     * listener to be informed when the task is done.
-     *
-     * @param musicProvider
-     * @param listener
-     */
-    public MusicProviderTask(MusicProvider musicProvider,
-            MusicProviderTaskListener listener) {
-        mMusicProvider = musicProvider;
-        mMusicProviderTaskListener = listener;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.os.AsyncTask#doInBackground(java.lang.Object[])
-     */
-    @Override
-    protected Void doInBackground(Void... arg0) {
-        try {
-            mMusicProvider.retreiveMedia();
-        } catch (JSONException e) {
-            Log.e(TAG, "::doInBackground:", e);
-        }
-        return null;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
-     */
-    @Override
-    protected void onPostExecute(Void result) {
-        mMusicProviderTaskListener.onMusicProviderTaskCompleted();
-    }
-
-}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTaskListener.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTaskListener.java
deleted file mode 100644
index b1d168f..0000000
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicProviderTaskListener.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All Rights Reserved.
- *
- * 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.example.android.musicservicedemo.browser;
-
-/**
- * Callback listener for completion of MusicProviderTask
- */
-public interface MusicProviderTaskListener {
-    public void onMusicProviderTaskCompleted();
-}
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicTrack.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicTrack.java
deleted file mode 100644
index 02ea899..0000000
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/browser/MusicTrack.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All Rights Reserved.
- *
- * 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.example.android.musicservicedemo.browser;
-
-/**
- * A class to model music track metadata.
- */
-public class MusicTrack {
-
-    private static final String TAG = "MusicTrack";
-
-    private String mTitle;
-    private String mAlbum;
-    private String mArtist;
-    private String mGenre;
-    private String mSource;
-    private String mImage;
-    private int mTrackNumber;
-    private int mTotalTrackCount;
-    private int mDuration;
-
-    /**
-     * Constructor creating a MusicTrack instance.
-     *
-     * @param title
-     * @param album
-     * @param artist
-     * @param genre
-     * @param source
-     * @param image
-     * @param trackNumber
-     * @param totalTrackCount
-     * @param duration
-     */
-    public MusicTrack(String title, String album, String artist, String genre, String source,
-            String image, int trackNumber, int totalTrackCount, int duration) {
-        this.mTitle = title;
-        this.mAlbum = album;
-        this.mArtist = artist;
-        this.mGenre = genre;
-        this.mSource = source;
-        this.mImage = image;
-        this.mTrackNumber = trackNumber;
-        this.mTotalTrackCount = totalTrackCount;
-        this.mDuration = duration;
-    }
-
-    public String getTitle() {
-        return mTitle;
-    }
-
-    public void setTitle(String mTitle) {
-        this.mTitle = mTitle;
-    }
-
-    public String getAlbum() {
-        return mAlbum;
-    }
-
-    public void setAlbum(String mAlbum) {
-        this.mAlbum = mAlbum;
-    }
-
-    public String getArtist() {
-        return mArtist;
-    }
-
-    public void setArtist(String mArtist) {
-        this.mArtist = mArtist;
-    }
-
-    public String getGenre() {
-        return mGenre;
-    }
-
-    public void setGenre(String mGenre) {
-        this.mGenre = mGenre;
-    }
-
-    public String getSource() {
-        return mSource;
-    }
-
-    public void setSource(String mSource) {
-        this.mSource = mSource;
-    }
-
-    public String getImage() {
-        return mImage;
-    }
-
-    public void setImage(String mImage) {
-        this.mImage = mImage;
-    }
-
-    public int getTrackNumber() {
-        return mTrackNumber;
-    }
-
-    public void setTrackNumber(int mTrackNumber) {
-        this.mTrackNumber = mTrackNumber;
-    }
-
-    public int getTotalTrackCount() {
-        return mTotalTrackCount;
-    }
-
-    public void setTotalTrackCount(int mTotalTrackCount) {
-        this.mTotalTrackCount = mTotalTrackCount;
-    }
-
-    public int getDuration() {
-        return mDuration;
-    }
-
-    public void setDuration(int mDuration) {
-        this.mDuration = mDuration;
-    }
-
-    public String toString() {
-        return mTitle;
-    }
-
-}
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index fc68183..8210403 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -62,16 +62,16 @@
     boolean mProgressDone = true;
 
     final int[] kNumberedIconResIDs = {
-        R.drawable.notification0,
-        R.drawable.notification1,
-        R.drawable.notification2,
-        R.drawable.notification3,
-        R.drawable.notification4,
-        R.drawable.notification5,
-        R.drawable.notification6,
-        R.drawable.notification7,
-        R.drawable.notification8,
-        R.drawable.notification9
+            R.drawable.notification0,
+            R.drawable.notification1,
+            R.drawable.notification2,
+            R.drawable.notification3,
+            R.drawable.notification4,
+            R.drawable.notification5,
+            R.drawable.notification6,
+            R.drawable.notification7,
+            R.drawable.notification8,
+            R.drawable.notification9
     };
     final int kUnnumberedIconResID = R.drawable.notificationx;
 
@@ -438,85 +438,85 @@
                     mNM.notify("cancel_madness", 7014, n);
                 }
             },
-        new Test("Off") {
-            public void run() {
-                PowerManager pm = (PowerManager) NotificationTestList.this.getSystemService(
-                        Context.POWER_SERVICE);
-                PowerManager.WakeLock wl = 
+            new Test("Off") {
+                public void run() {
+                    PowerManager pm = (PowerManager) NotificationTestList.this.getSystemService(
+                            Context.POWER_SERVICE);
+                    PowerManager.WakeLock wl =
                             pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "sound");
-                wl.acquire();
+                    wl.acquire();
 
-                pm.goToSleep(SystemClock.uptimeMillis());
+                    pm.goToSleep(SystemClock.uptimeMillis());
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-                Log.d(TAG, "n.sound=" + n.sound);
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+                    Log.d(TAG, "n.sound=" + n.sound);
 
-                mNM.notify(1, n);
+                    mNM.notify(1, n);
 
-                Log.d(TAG, "releasing wake lock");
-                wl.release();
-                Log.d(TAG, "released wake lock");
-            }
-        },
+                    Log.d(TAG, "releasing wake lock");
+                    wl.release();
+                    Log.d(TAG, "released wake lock");
+                }
+            },
 
-        new Test("Cancel #1") {
-            public void run()
-            {
-                mNM.cancel(1);
-            }
-        },
+            new Test("Cancel #1") {
+                public void run()
+                {
+                    mNM.cancel(1);
+                }
+            },
 
-        new Test("Custom Button") {
-            public void run() {
-                RemoteViews view = new RemoteViews(getPackageName(), R.layout.button_notification);
-                view.setOnClickPendingIntent(R.id.button, makeIntent2());
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setOngoing(true)
-                        .setCustomContentView(view)
-                        .build();
+            new Test("Custom Button") {
+                public void run() {
+                    RemoteViews view = new RemoteViews(getPackageName(), R.layout.button_notification);
+                    view.setOnClickPendingIntent(R.id.button, makeIntent2());
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setOngoing(true)
+                            .setCustomContentView(view)
+                            .build();
 
-                mNM.notify(1, n);
-            }
-        },
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Action Button") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setOngoing(true)
-                        .addAction(new Notification.Action.Builder(
-                                Icon.createWithResource(NotificationTestList.this,
-                                        R.drawable.ic_statusbar_chat),
-                                "Button", makeIntent2())
-                                .build())
-                        .build();
+            new Test("Action Button") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setOngoing(true)
+                            .addAction(new Notification.Action.Builder(
+                                    Icon.createWithResource(NotificationTestList.this,
+                                            R.drawable.ic_statusbar_chat),
+                                    "Button", makeIntent2())
+                                    .build())
+                            .build();
 
-                mNM.notify(1, n);
-            }
-        },
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("with intent") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent2())
-                        .setOngoing(true)
-                        .build();
+            new Test("with intent") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent2())
+                            .setOngoing(true)
+                            .build();
 
-                mNM.notify(1, n);
-            }
-        },
+                    mNM.notify(1, n);
+                }
+            },
 
             new Test("Is blocked?") {
                 public void run() {
@@ -534,484 +534,484 @@
                 }
             },
 
-        new Test("Whens") {
-            public void run()
-            {
-                Notification.Builder n = new Notification.Builder(
-                        NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setContentTitle(name)
-                        .setOngoing(true);
+            new Test("Whens") {
+                public void run()
+                {
+                    Notification.Builder n = new Notification.Builder(
+                            NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setContentTitle(name)
+                            .setOngoing(true);
 
-                mNM.notify(1, n.setContentTitle("(453) 123-2328")
-                .setWhen(System.currentTimeMillis()-(1000*60*60*24))
-                .build());
+                    mNM.notify(1, n.setContentTitle("(453) 123-2328")
+                            .setWhen(System.currentTimeMillis()-(1000*60*60*24))
+                            .build());
 
-                mNM.notify(1, n.setContentTitle("Mark Willem, Me (2)")
-                .setWhen(System.currentTimeMillis())
-                .build());
+                    mNM.notify(1, n.setContentTitle("Mark Willem, Me (2)")
+                            .setWhen(System.currentTimeMillis())
+                            .build());
 
-                mNM.notify(1, n.setContentTitle("Sophia Winterlanden")
-                        .setWhen(System.currentTimeMillis() + (1000 * 60 * 60 * 24))
-                        .build());
-            }
-        },
-
-        new Test("Bad Icon #1 (when=create)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.layout.chrono_notification /* not an icon */)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Bad Icon #1 (when=now)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.layout.chrono_notification /* not an icon */)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Null Icon #1 (when=now)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(0)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Bad resource #1 (when=create)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Bad resource #1 (when=now)") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle("Persistent #1")
-                        .setContentText("This is the same notification!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Times") {
-            public void run()
-            {
-                long now = System.currentTimeMillis();
-
-                timeNotification(7, "24 hours from now", now+(1000*60*60*24));
-                timeNotification(6, "12:01:00 from now", now+(1000*60*60*12)+(60*1000));
-                timeNotification(5, "12 hours from now", now+(1000*60*60*12));
-                timeNotification(4, "now", now);
-                timeNotification(3, "11:59:00 ago", now-((1000*60*60*12)-(60*1000)));
-                timeNotification(2, "12 hours ago", now-(1000*60*60*12));
-                timeNotification(1, "24 hours ago", now-(1000*60*60*24));
-            }
-        },
-        new StateStress("Stress - Ongoing / Latest", 100, 100, new Runnable[] {
-                new Runnable() {
-                    public void run() {
-                        Log.d(TAG, "Stress - Ongoing/Latest 0");
-                        Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                                .setSmallIcon(R.drawable.icon3)
-                                .setWhen(System.currentTimeMillis())
-                                .setContentTitle("Stress - Ongoing")
-                                .setContentText("Notify me!!!")
-                                .setOngoing(true)
-                                .build();
-                        mNM.notify(1, n);
-                    }
-                },
-                new Runnable() {
-                    public void run() {
-                        Log.d(TAG, "Stress - Ongoing/Latest 1");
-                        Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                                .setSmallIcon(R.drawable.icon4)
-                                .setWhen(System.currentTimeMillis())
-                                .setContentTitle("Stress - Latest")
-                                .setContentText("Notify me!!!")
-                                .build();
-                        mNM.notify(1, n);
-                    }
+                    mNM.notify(1, n.setContentTitle("Sophia Winterlanden")
+                            .setWhen(System.currentTimeMillis() + (1000 * 60 * 60 * 24))
+                            .build());
                 }
-            }),
+            },
 
-        new Test("Long") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("v. noisy",
-                        "channel for sound and a custom vibration", IMPORTANCE_DEFAULT);
-                channel.enableVibration(true);
-                channel.setVibrationPattern(new long[] {
-                        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
-                        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
-                        300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 });
-                mNM.createNotificationChannel(channel);
+            new Test("Bad Icon #1 (when=create)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.layout.chrono_notification /* not an icon */)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "v. noisy")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Bad Icon #1 (when=now)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.layout.chrono_notification /* not an icon */)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Progress #1") {
-            public void run() {
-                final boolean PROGRESS_UPDATES_WHEN = true;
-                if (!mProgressDone) return;
-                mProgressDone = false;
-                Thread t = new Thread() {
-                    public void run() {
-                        int x = 0;
-                        final Notification.Builder n = new Notification.Builder(
-                                NotificationTestList.this, "low")
-                                .setSmallIcon(R.drawable.icon1)
-                                .setContentTitle(name)
-                                .setOngoing(true);
+            new Test("Null Icon #1 (when=now)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(0)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-                        while (!mProgressDone) {
-                            n.setWhen(PROGRESS_UPDATES_WHEN
-                                    ? System.currentTimeMillis()
-                                    : mActivityCreateTime);
-                            n.setProgress(100, x, false);
-                            n.setContentText("Progress: " + x + "%");
+            new Test("Bad resource #1 (when=create)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
+                    mNM.notify(1, n);
+                }
+            },
 
-                            mNM.notify(500, n.build());
-                            x = (x + 7) % 100;
+            new Test("Bad resource #1 (when=now)") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle("Persistent #1")
+                            .setContentText("This is the same notification!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    n.contentView.setInt(1 /*bogus*/, "bogus method", 666);
+                    mNM.notify(1, n);
+                }
+            },
 
-                            try {
-                                Thread.sleep(1000);
-                            } catch (InterruptedException e) {
-                                break;
-                            }
+            new Test("Times") {
+                public void run()
+                {
+                    long now = System.currentTimeMillis();
+
+                    timeNotification(7, "24 hours from now", now+(1000*60*60*24));
+                    timeNotification(6, "12:01:00 from now", now+(1000*60*60*12)+(60*1000));
+                    timeNotification(5, "12 hours from now", now+(1000*60*60*12));
+                    timeNotification(4, "now", now);
+                    timeNotification(3, "11:59:00 ago", now-((1000*60*60*12)-(60*1000)));
+                    timeNotification(2, "12 hours ago", now-(1000*60*60*12));
+                    timeNotification(1, "24 hours ago", now-(1000*60*60*24));
+                }
+            },
+            new StateStress("Stress - Ongoing / Latest", 100, 100, new Runnable[] {
+                    new Runnable() {
+                        public void run() {
+                            Log.d(TAG, "Stress - Ongoing/Latest 0");
+                            Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon3)
+                                    .setWhen(System.currentTimeMillis())
+                                    .setContentTitle("Stress - Ongoing")
+                                    .setContentText("Notify me!!!")
+                                    .setOngoing(true)
+                                    .build();
+                            mNM.notify(1, n);
+                        }
+                    },
+                    new Runnable() {
+                        public void run() {
+                            Log.d(TAG, "Stress - Ongoing/Latest 1");
+                            Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon4)
+                                    .setWhen(System.currentTimeMillis())
+                                    .setContentTitle("Stress - Latest")
+                                    .setContentText("Notify me!!!")
+                                    .build();
+                            mNM.notify(1, n);
                         }
                     }
-                };
-                t.start();
-            }
-        },
+            }),
 
-        new Test("Stop Progress") {
-            public void run() {
-                mProgressDone = true;
-                mNM.cancel(500);
-            }
-        },
+            new Test("Long") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("v. noisy",
+                            "channel for sound and a custom vibration", IMPORTANCE_DEFAULT);
+                    channel.enableVibration(true);
+                    channel.setVibrationPattern(new long[] {
+                            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+                            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+                            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 });
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Blue Lights") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("blue",
-                        "blue", IMPORTANCE_DEFAULT);
-                channel.enableLights(true);
-                channel.setLightColor(0xff0000ff);
-                mNM.createNotificationChannel(channel);
+                    Notification n = new Notification.Builder(NotificationTestList.this, "v. noisy")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "blue")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Progress #1") {
+                public void run() {
+                    final boolean PROGRESS_UPDATES_WHEN = true;
+                    if (!mProgressDone) return;
+                    mProgressDone = false;
+                    Thread t = new Thread() {
+                        public void run() {
+                            int x = 0;
+                            final Notification.Builder n = new Notification.Builder(
+                                    NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon1)
+                                    .setContentTitle(name)
+                                    .setOngoing(true);
 
-        new Test("Red Lights") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("red",
-                        "red", IMPORTANCE_DEFAULT);
-                channel.enableLights(true);
-                channel.setLightColor(0xffff0000);
-                mNM.createNotificationChannel(channel);
+                            while (!mProgressDone) {
+                                n.setWhen(PROGRESS_UPDATES_WHEN
+                                        ? System.currentTimeMillis()
+                                        : mActivityCreateTime);
+                                n.setProgress(100, x, false);
+                                n.setContentText("Progress: " + x + "%");
 
-                Notification n = new Notification.Builder(NotificationTestList.this, "red")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+                                mNM.notify(500, n.build());
+                                x = (x + 7) % 100;
 
-        new Test("Lights off") {
-            public void run()
-            {
-                Notification n = new Notification.Builder(NotificationTestList.this, "default")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Alert once") {
-            public void run()
-            {
-                Notification n = new Notification.Builder(NotificationTestList.this, "high")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setContentTitle(name)
-                        .setOnlyAlertOnce(true)
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Resource Sound") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("res_sound",
-                        "resource sound", IMPORTANCE_DEFAULT);
-                channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
-                        getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
-                mNM.createNotificationChannel(channel);
-
-                Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-                Log.d(TAG, "n.sound=" + n.sound);
-
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Sound and Cancel") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("res_sound",
-                        "resource sound", IMPORTANCE_DEFAULT);
-                channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
-                        getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
-                mNM.createNotificationChannel(channel);
-
-                Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-
-                mNM.notify(1, n);
-                SystemClock.sleep(600);
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Vibrate and cancel") {
-            public void run()
-            {
-                NotificationChannel channel = new NotificationChannel("vibrate",
-                        "vibrate", IMPORTANCE_DEFAULT);
-                channel.enableVibration(true);
-                channel.setVibrationPattern(new long[] {0, 700, 500, 1000, 0, 700, 500, 1000,
-                        0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000,
-                        0, 700, 500, 1000, 0, 700, 500, 1000});
-                mNM.createNotificationChannel(channel);
-
-                Notification n = new Notification.Builder(NotificationTestList.this, "vibrate")
-                        .setSmallIcon(R.drawable.stat_sys_phone)
-                        .setContentTitle(name)
-                        .build();
-
-                mNM.notify(1, n);
-                SystemClock.sleep(500);
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Vibrate pattern") {
-            public void run()
-            {
-                mVibrator.vibrate(new long[] { 250, 1000, 500, 2000 }, -1);
-            }
-        },
-
-        new Test("Vibrate pattern repeating") {
-            public void run()
-            {
-                mVibrator.vibrate(new long[] { 250, 1000, 500 }, 1);
-            }
-        },
-
-        new Test("Vibrate 3s") {
-            public void run()
-            {
-                mVibrator.vibrate(3000);
-            }
-        },
-
-        new Test("Vibrate 100s") {
-            public void run()
-            {
-                mVibrator.vibrate(100000);
-            }
-        },
-
-        new Test("Vibrate off") {
-            public void run()
-            {
-                mVibrator.cancel();
-            }
-        },
-
-        new Test("Cancel #1") {
-            public void run() {
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Cancel #1 in 3 sec") {
-            public void run() {
-                mHandler.postDelayed(new Runnable() {
-                            public void run() {
-                                Log.d(TAG, "Cancelling now...");
-                                mNM.cancel(1);
+                                try {
+                                    Thread.sleep(1000);
+                                } catch (InterruptedException e) {
+                                    break;
+                                }
                             }
-                        }, 3000);
-            }
-        },
+                        }
+                    };
+                    t.start();
+                }
+            },
 
-        new Test("Cancel #2") {
-            public void run() {
-                mNM.cancel(2);
-            }
-        },
+            new Test("Stop Progress") {
+                public void run() {
+                    mProgressDone = true;
+                    mNM.cancel(500);
+                }
+            },
 
-        new Test("Persistent #1") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this)
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Blue Lights") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("blue",
+                            "blue", IMPORTANCE_DEFAULT);
+                    channel.enableLights(true);
+                    channel.setLightColor(0xff0000ff);
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Persistent #1 in 3 sec") {
-            public void run() {
-                mHandler.postDelayed(new Runnable() {
-                            public void run() {
-                                String message = "            "
-                                        + "tick tock tick tock\n\nSometimes notifications can "
-                                        + "be really long and wrap to more than one line.\n"
-                                        + "Sometimes."
-                                        + "Ohandwhathappensifwehaveonereallylongstringarewesure"
-                                        + "thatwesegmentitcorrectly?\n";
-                                Notification n = new Notification.Builder(
-                                        NotificationTestList.this, "low")
-                                        .setSmallIcon(R.drawable.icon1)
-                                        .setContentTitle(name)
-                                        .setContentText("This is still a notification!!!")
-                                        .setContentIntent(makeIntent())
-                                        .setStyle(new Notification.BigTextStyle().bigText(message))
-                                        .build();
-                                mNM.notify(1, n);
-                            }
-                        }, 3000);
-            }
-        },
+                    Notification n = new Notification.Builder(NotificationTestList.this, "blue")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Persistent #2") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(2, n);
-            }
-        },
+            new Test("Red Lights") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("red",
+                            "red", IMPORTANCE_DEFAULT);
+                    channel.enableLights(true);
+                    channel.setLightColor(0xffff0000);
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Persistent #3") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(3, n);
-            }
-        },
+                    Notification n = new Notification.Builder(NotificationTestList.this, "red")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Persistent #2 Vibrate") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .setDefaults(Notification.DEFAULT_VIBRATE)
-                        .build();
-                mNM.notify(2, n);
-            }
-        },
+            new Test("Lights off") {
+                public void run()
+                {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "default")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Persistent #1 - different icon") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon2)
-                        .setWhen(mActivityCreateTime)
-                        .setContentTitle(name)
-                        .setContentText("This is a notification!!!")
-                        .setContentIntent(makeIntent())
-                        .build();
-                mNM.notify(1, n);
-            }
-        },
+            new Test("Alert once") {
+                public void run()
+                {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "high")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle(name)
+                            .setOnlyAlertOnce(true)
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
 
-        new Test("Chronometer Start") {
-            public void run() {
-                Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                        .setSmallIcon(R.drawable.icon1)
-                        .setWhen(System.currentTimeMillis())
-                        .setContentTitle(name)
-                        .setContentIntent(makeIntent())
-                        .setOngoing(true)
-                        .setUsesChronometer(true)
-                        .build();
-                mNM.notify(2, n);
-            }
-        },
+            new Test("Resource Sound") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("res_sound",
+                            "resource sound", IMPORTANCE_DEFAULT);
+                    channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
+                            getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
+                    mNM.createNotificationChannel(channel);
 
-        new Test("Chronometer Stop") {
-            public void run() {
-                mHandler.postDelayed(new Runnable() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+                    Log.d(TAG, "n.sound=" + n.sound);
+
+                    mNM.notify(1, n);
+                }
+            },
+
+            new Test("Sound and Cancel") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("res_sound",
+                            "resource sound", IMPORTANCE_DEFAULT);
+                    channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
+                            getPackageName() + "/raw/ringer"), Notification.AUDIO_ATTRIBUTES_DEFAULT);
+                    mNM.createNotificationChannel(channel);
+
+                    Notification n = new Notification.Builder(NotificationTestList.this, "res_sound")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+
+                    mNM.notify(1, n);
+                    SystemClock.sleep(600);
+                    mNM.cancel(1);
+                }
+            },
+
+            new Test("Vibrate and cancel") {
+                public void run()
+                {
+                    NotificationChannel channel = new NotificationChannel("vibrate",
+                            "vibrate", IMPORTANCE_DEFAULT);
+                    channel.enableVibration(true);
+                    channel.setVibrationPattern(new long[] {0, 700, 500, 1000, 0, 700, 500, 1000,
+                            0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000, 0, 700, 500, 1000,
+                            0, 700, 500, 1000, 0, 700, 500, 1000});
+                    mNM.createNotificationChannel(channel);
+
+                    Notification n = new Notification.Builder(NotificationTestList.this, "vibrate")
+                            .setSmallIcon(R.drawable.stat_sys_phone)
+                            .setContentTitle(name)
+                            .build();
+
+                    mNM.notify(1, n);
+                    SystemClock.sleep(500);
+                    mNM.cancel(1);
+                }
+            },
+
+            new Test("Vibrate pattern") {
+                public void run()
+                {
+                    mVibrator.vibrate(new long[] { 250, 1000, 500, 2000 }, -1);
+                }
+            },
+
+            new Test("Vibrate pattern repeating") {
+                public void run()
+                {
+                    mVibrator.vibrate(new long[] { 250, 1000, 500 }, 1);
+                }
+            },
+
+            new Test("Vibrate 3s") {
+                public void run()
+                {
+                    mVibrator.vibrate(3000);
+                }
+            },
+
+            new Test("Vibrate 100s") {
+                public void run()
+                {
+                    mVibrator.vibrate(100000);
+                }
+            },
+
+            new Test("Vibrate off") {
+                public void run()
+                {
+                    mVibrator.cancel();
+                }
+            },
+
+            new Test("Cancel #1") {
+                public void run() {
+                    mNM.cancel(1);
+                }
+            },
+
+            new Test("Cancel #1 in 3 sec") {
+                public void run() {
+                    mHandler.postDelayed(new Runnable() {
+                        public void run() {
+                            Log.d(TAG, "Cancelling now...");
+                            mNM.cancel(1);
+                        }
+                    }, 3000);
+                }
+            },
+
+            new Test("Cancel #2") {
+                public void run() {
+                    mNM.cancel(2);
+                }
+            },
+
+            new Test("Persistent #1") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this)
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
+
+            new Test("Persistent #1 in 3 sec") {
+                public void run() {
+                    mHandler.postDelayed(new Runnable() {
+                        public void run() {
+                            String message = "            "
+                                    + "tick tock tick tock\n\nSometimes notifications can "
+                                    + "be really long and wrap to more than one line.\n"
+                                    + "Sometimes."
+                                    + "Ohandwhathappensifwehaveonereallylongstringarewesure"
+                                    + "thatwesegmentitcorrectly?\n";
+                            Notification n = new Notification.Builder(
+                                    NotificationTestList.this, "low")
+                                    .setSmallIcon(R.drawable.icon1)
+                                    .setContentTitle(name)
+                                    .setContentText("This is still a notification!!!")
+                                    .setContentIntent(makeIntent())
+                                    .setStyle(new Notification.BigTextStyle().bigText(message))
+                                    .build();
+                            mNM.notify(1, n);
+                        }
+                    }, 3000);
+                }
+            },
+
+            new Test("Persistent #2") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(2, n);
+                }
+            },
+
+            new Test("Persistent #3") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(3, n);
+                }
+            },
+
+            new Test("Persistent #2 Vibrate") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .setDefaults(Notification.DEFAULT_VIBRATE)
+                            .build();
+                    mNM.notify(2, n);
+                }
+            },
+
+            new Test("Persistent #1 - different icon") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setWhen(mActivityCreateTime)
+                            .setContentTitle(name)
+                            .setContentText("This is a notification!!!")
+                            .setContentIntent(makeIntent())
+                            .build();
+                    mNM.notify(1, n);
+                }
+            },
+
+            new Test("Chronometer Start") {
+                public void run() {
+                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                            .setSmallIcon(R.drawable.icon1)
+                            .setWhen(System.currentTimeMillis())
+                            .setContentTitle(name)
+                            .setContentIntent(makeIntent())
+                            .setOngoing(true)
+                            .setUsesChronometer(true)
+                            .build();
+                    mNM.notify(2, n);
+                }
+            },
+
+            new Test("Chronometer Stop") {
+                public void run() {
+                    mHandler.postDelayed(new Runnable() {
                         public void run() {
                             Log.d(TAG, "Chronometer Stop");
                             Notification n = new Notification.Builder(
@@ -1024,121 +1024,121 @@
                             mNM.notify(2, n);
                         }
                     }, 3000);
-            }
-        },
-
-        new Test("Sequential Persistent") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.notify(2, notificationWithNumbers(name, 2));
-            }
-        },
-
-        new Test("Replace Persistent") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.notify(1, notificationWithNumbers(name, 1));
-            }
-        },
-
-        new Test("Run and Cancel (n=1)") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.cancel(1);
-            }
-        },
-
-        new Test("Run an Cancel (n=2)") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-                mNM.notify(2, notificationWithNumbers(name, 2));
-                mNM.cancel(2);
-            }
-        },
-
-        // Repeatedly notify and cancel -- triggers bug #670627
-        new Test("Bug 670627") {
-            public void run() {
-                for (int i = 0; i < 10; i++) {
-                  Log.d(TAG, "Add two notifications");
-                  mNM.notify(1, notificationWithNumbers(name, 1));
-                  mNM.notify(2, notificationWithNumbers(name, 2));
-                  Log.d(TAG, "Cancel two notifications");
-                  mNM.cancel(1);
-                  mNM.cancel(2);
                 }
-            }
-        },
+            },
 
-        new Test("Ten Notifications") {
-            public void run() {
-                for (int i = 0; i < 10; i++) {
-                    Notification n = new Notification.Builder(NotificationTestList.this, "low")
-                            .setSmallIcon(kNumberedIconResIDs[i])
-                            .setContentTitle("Persistent #" + i)
-                            .setContentText("Notify me!!!" + i)
-                            .setOngoing(i < 2)
-                            .setNumber(i)
-                            .build();
-                    mNM.notify((i+1)*10, n);
+            new Test("Sequential Persistent") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.notify(2, notificationWithNumbers(name, 2));
                 }
-            }
-        },
-        
-        new Test("Cancel eight notifications") {
-            public void run() {
-                for (int i = 1; i < 9; i++) {
-                    mNM.cancel((i+1)*10);
+            },
+
+            new Test("Replace Persistent") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.notify(1, notificationWithNumbers(name, 1));
                 }
-            }
-        },
-        
-        new Test("Cancel the other two notifications") {
-            public void run() {
-                mNM.cancel(10);
-                mNM.cancel(100);
-            }
-        },
-        
-        new Test("Persistent with numbers 1") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 1));
-            }
-        },
+            },
 
-        new Test("Persistent with numbers 22") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 22));
-            }
-        },
+            new Test("Run and Cancel (n=1)") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.cancel(1);
+                }
+            },
 
-        new Test("Persistent with numbers 333") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 333));
-            }
-        },
+            new Test("Run an Cancel (n=2)") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                    mNM.notify(2, notificationWithNumbers(name, 2));
+                    mNM.cancel(2);
+                }
+            },
 
-        new Test("Persistent with numbers 4444") {
-            public void run() {
-                mNM.notify(1, notificationWithNumbers(name, 4444));
-            }
-        },
+            // Repeatedly notify and cancel -- triggers bug #670627
+            new Test("Bug 670627") {
+                public void run() {
+                    for (int i = 0; i < 10; i++) {
+                        Log.d(TAG, "Add two notifications");
+                        mNM.notify(1, notificationWithNumbers(name, 1));
+                        mNM.notify(2, notificationWithNumbers(name, 2));
+                        Log.d(TAG, "Cancel two notifications");
+                        mNM.cancel(1);
+                        mNM.cancel(2);
+                    }
+                }
+            },
 
-        new Test("Crash") {
-            public void run()
-            {
-                PowerManager.WakeLock wl =
-                        ((PowerManager) NotificationTestList.this.getSystemService(Context.POWER_SERVICE))
-                                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "crasher");
-                wl.acquire();
-                mHandler.postDelayed(new Runnable() {
-                            public void run() {
-                                throw new RuntimeException("Die!");
-                            }
-                        }, 10000);
+            new Test("Ten Notifications") {
+                public void run() {
+                    for (int i = 0; i < 10; i++) {
+                        Notification n = new Notification.Builder(NotificationTestList.this, "low")
+                                .setSmallIcon(kNumberedIconResIDs[i])
+                                .setContentTitle("Persistent #" + i)
+                                .setContentText("Notify me!!!" + i)
+                                .setOngoing(i < 2)
+                                .setNumber(i)
+                                .build();
+                        mNM.notify((i+1)*10, n);
+                    }
+                }
+            },
 
-            }
-        },
+            new Test("Cancel eight notifications") {
+                public void run() {
+                    for (int i = 1; i < 9; i++) {
+                        mNM.cancel((i+1)*10);
+                    }
+                }
+            },
+
+            new Test("Cancel the other two notifications") {
+                public void run() {
+                    mNM.cancel(10);
+                    mNM.cancel(100);
+                }
+            },
+
+            new Test("Persistent with numbers 1") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 1));
+                }
+            },
+
+            new Test("Persistent with numbers 22") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 22));
+                }
+            },
+
+            new Test("Persistent with numbers 333") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 333));
+                }
+            },
+
+            new Test("Persistent with numbers 4444") {
+                public void run() {
+                    mNM.notify(1, notificationWithNumbers(name, 4444));
+                }
+            },
+
+            new Test("Crash") {
+                public void run()
+                {
+                    PowerManager.WakeLock wl =
+                            ((PowerManager) NotificationTestList.this.getSystemService(Context.POWER_SERVICE))
+                                    .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "crasher");
+                    wl.acquire();
+                    mHandler.postDelayed(new Runnable() {
+                        public void run() {
+                            throw new RuntimeException("Die!");
+                        }
+                    }, 10000);
+
+                }
+            },
 
     };
 
@@ -1212,4 +1212,3 @@
         return Bitmap.createBitmap(bd.getBitmap());
     }
 }
-
diff --git a/tests/net/OWNERS b/tests/net/OWNERS
new file mode 100644
index 0000000..fa26997
--- /dev/null
+++ b/tests/net/OWNERS
@@ -0,0 +1,7 @@
+set noparent
+
+per-file Android.mk = build.master@android.com
+
+ek@google.com
+hugobenichi@google.com
+lorenzo@google.com
diff --git a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
index 1ddaf66..0dedf70 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -46,6 +46,7 @@
 import java.net.InetAddress;
 import java.util.ArrayList;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.runner.RunWith;
 import org.junit.Test;
@@ -73,6 +74,11 @@
         mContentResolver = new MockContentResolver(mContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        FakeSettingsProvider.clearSettingsProvider();
+    }
+
+    @After public void tearDown() throws Exception {
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     private void setupFunctioningHardwareInterface() {
@@ -81,9 +87,14 @@
                 .thenReturn(true);
     }
 
+    private void enableOffload() {
+        Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
+    }
+
     @Test
-    public void testNoSettingsValueAllowsStart() {
+    public void testNoSettingsValueDefaultDisabledDoesNotStart() {
         setupFunctioningHardwareInterface();
+        when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(1);
         try {
             Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED);
             fail();
@@ -94,6 +105,28 @@
         offload.start();
 
         final InOrder inOrder = inOrder(mHardware);
+        inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
+        inOrder.verify(mHardware, never()).initOffloadConfig();
+        inOrder.verify(mHardware, never()).initOffloadControl(
+                any(OffloadHardwareInterface.ControlCallback.class));
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testNoSettingsValueDefaultEnabledDoesStart() {
+        setupFunctioningHardwareInterface();
+        when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(0);
+        try {
+            Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED);
+            fail();
+        } catch (SettingNotFoundException expected) {}
+
+        final OffloadController offload =
+                new OffloadController(null, mHardware, mContentResolver, new SharedLog("test"));
+        offload.start();
+
+        final InOrder inOrder = inOrder(mHardware);
+        inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
         inOrder.verify(mHardware, times(1)).initOffloadConfig();
         inOrder.verify(mHardware, times(1)).initOffloadControl(
                 any(OffloadHardwareInterface.ControlCallback.class));
@@ -110,6 +143,7 @@
         offload.start();
 
         final InOrder inOrder = inOrder(mHardware);
+        inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
         inOrder.verify(mHardware, times(1)).initOffloadConfig();
         inOrder.verify(mHardware, times(1)).initOffloadControl(
                 any(OffloadHardwareInterface.ControlCallback.class));
@@ -126,6 +160,7 @@
         offload.start();
 
         final InOrder inOrder = inOrder(mHardware);
+        inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
         inOrder.verify(mHardware, never()).initOffloadConfig();
         inOrder.verify(mHardware, never()).initOffloadControl(anyObject());
         inOrder.verifyNoMoreInteractions();
@@ -134,11 +169,14 @@
     @Test
     public void testSetUpstreamLinkPropertiesWorking() throws Exception {
         setupFunctioningHardwareInterface();
+        enableOffload();
+
         final OffloadController offload =
                 new OffloadController(null, mHardware, mContentResolver, new SharedLog("test"));
         offload.start();
 
         final InOrder inOrder = inOrder(mHardware);
+        inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
         inOrder.verify(mHardware, times(1)).initOffloadConfig();
         inOrder.verify(mHardware, times(1)).initOffloadControl(
                 any(OffloadHardwareInterface.ControlCallback.class));
diff --git a/tools/aapt/pseudolocalize.cpp b/tools/aapt/pseudolocalize.cpp
index c7fee2c..5c47e0f 100644
--- a/tools/aapt/pseudolocalize.cpp
+++ b/tools/aapt/pseudolocalize.cpp
@@ -360,9 +360,15 @@
     String16 result;
     bool lastspace = true;
     bool space = true;
+    bool escape = false;
+    const char16_t ESCAPE_CHAR = '\\';
     for (size_t i=0; i<source.size(); i++) {
         char16_t c = s[i];
-        space = is_space(c);
+        if (!escape && c == ESCAPE_CHAR) {
+          escape = true;
+          continue;
+        }
+        space = (!escape && is_space(c)) || (escape && (c == 'n' || c == 't'));
         if (lastspace && !space) {
           // Word start
           result += k_rlm + k_rlo;
@@ -371,6 +377,10 @@
           result += k_pdf + k_rlm;
         }
         lastspace = space;
+        if (escape) {
+          result.append(&ESCAPE_CHAR, 1);
+          escape=false;
+        }
         result.append(&c, 1);
     }
     if (!lastspace) {
diff --git a/tools/aapt/tests/Pseudolocales_test.cpp b/tools/aapt/tests/Pseudolocales_test.cpp
index 4670e9f..a6aed3a 100644
--- a/tools/aapt/tests/Pseudolocales_test.cpp
+++ b/tools/aapt/tests/Pseudolocales_test.cpp
@@ -87,6 +87,10 @@
                 "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n" \
                 "  \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n",
                 PSEUDO_BIDI);
+  simple_helper("hello\\nworld\\n",
+                "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\\n"
+                "\xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\\n",
+                PSEUDO_BIDI);
 }
 
 TEST(Pseudolocales, SimpleICU) {
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index d39a8a8..14d05fd 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -111,6 +111,8 @@
         "proto/TableProtoDeserializer.cpp",
         "proto/TableProtoSerializer.cpp",
         "split/TableSplitter.cpp",
+        "text/Unicode.cpp",
+        "text/Utf8Iterator.cpp",
         "unflatten/BinaryResourceParser.cpp",
         "unflatten/ResChunkPullParser.cpp",
         "util/BigBuffer.cpp",
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 5978cdd..c5d38ab 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -27,7 +27,7 @@
 static const char* sMajorVersion = "2";
 
 // Update minor version whenever a feature or flag is added.
-static const char* sMinorVersion = "17";
+static const char* sMinorVersion = "18";
 
 int PrintVersion() {
   std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
diff --git a/tools/aapt2/OWNERS b/tools/aapt2/OWNERS
new file mode 100644
index 0000000..d76233e
--- /dev/null
+++ b/tools/aapt2/OWNERS
@@ -0,0 +1,2 @@
+set noparent
+adamlesinski@google.com
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index e189144..d47a529 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -95,6 +95,11 @@
   ASSERT_THAT(str, NotNull());
   EXPECT_THAT(*str, StrValueEq("?123"));
   EXPECT_THAT(str->untranslatable_sections, IsEmpty());
+
+  ASSERT_TRUE(TestParse(R"(<string name="bar">This isn\’t a bad string</string>)"));
+  str = test::GetValue<String>(&table_, "string/bar");
+  ASSERT_THAT(str, NotNull());
+  EXPECT_THAT(*str, StrValueEq("This isn’t a bad string"));
 }
 
 TEST_F(ResourceParserTest, ParseFormattedString) {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 168004f..ab59560 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -15,20 +15,24 @@
  */
 
 #include "ResourceTable.h"
-#include "ConfigDescription.h"
-#include "NameMangler.h"
-#include "ResourceValues.h"
-#include "ValueVisitor.h"
-#include "util/Util.h"
 
-#include <android-base/logging.h>
-#include <androidfw/ResourceTypes.h>
 #include <algorithm>
 #include <memory>
 #include <string>
 #include <tuple>
 
-using android::StringPiece;
+#include "android-base/logging.h"
+#include "androidfw/ResourceTypes.h"
+
+#include "ConfigDescription.h"
+#include "NameMangler.h"
+#include "ResourceValues.h"
+#include "ValueVisitor.h"
+#include "text/Unicode.h"
+#include "util/Util.h"
+
+using ::aapt::text::IsValidResourceEntryName;
+using ::android::StringPiece;
 
 namespace aapt {
 
@@ -283,12 +287,9 @@
   return CollisionResult::kConflict;
 }
 
-static constexpr const char* kValidNameChars = "._-";
-
 static StringPiece ValidateName(const StringPiece& name) {
-  auto iter = util::FindNonAlphaNumericAndNotInSet(name, kValidNameChars);
-  if (iter != name.end()) {
-    return StringPiece(iter, 1);
+  if (!IsValidResourceEntryName(name)) {
+    return name;
   }
   return {};
 }
diff --git a/tools/aapt2/compile/Pseudolocalizer.cpp b/tools/aapt2/compile/Pseudolocalizer.cpp
index 15a3d8c..3a515fa 100644
--- a/tools/aapt2/compile/Pseudolocalizer.cpp
+++ b/tools/aapt2/compile/Pseudolocalizer.cpp
@@ -445,9 +445,15 @@
   std::string result;
   bool lastspace = true;
   bool space = true;
+  bool escape = false;
+  const char ESCAPE_CHAR = '\\';
   for (size_t i = 0; i < source.size(); i++) {
     char c = s[i];
-    space = isspace(c);
+    if (!escape && c == ESCAPE_CHAR) {
+      escape = true;
+      continue;
+    }
+    space = (!escape && isspace(c)) || (escape && (c == 'n' || c == 't'));
     if (lastspace && !space) {
       // Word start
       result += kRlm + kRlo;
@@ -456,6 +462,10 @@
       result += kPdf + kRlm;
     }
     lastspace = space;
+    if (escape) {
+      result.append(&ESCAPE_CHAR, 1);
+      escape=false;
+    }
     result.append(&c, 1);
   }
   if (!lastspace) {
diff --git a/tools/aapt2/compile/Pseudolocalizer_test.cpp b/tools/aapt2/compile/Pseudolocalizer_test.cpp
index d3b7b02..65d2472 100644
--- a/tools/aapt2/compile/Pseudolocalizer_test.cpp
+++ b/tools/aapt2/compile/Pseudolocalizer_test.cpp
@@ -97,6 +97,11 @@
       "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n"
       "  \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n",
       Pseudolocalizer::Method::kBidi));
+  EXPECT_TRUE(
+      SimpleHelper("hello\\nworld\\n",
+                   "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\\n"
+                   "\xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\\n",
+                   Pseudolocalizer::Method::kBidi));
 }
 
 TEST(PseudolocalizerTest, SimpleICU) {
diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp
index 0711749..bfebedef 100644
--- a/tools/aapt2/flatten/XmlFlattener.cpp
+++ b/tools/aapt2/flatten/XmlFlattener.cpp
@@ -257,9 +257,11 @@
 
       // Process plain strings to make sure they get properly escaped.
       StringPiece raw_value = xml_attr->value;
-      util::StringBuilder str_builder;
+
+      util::StringBuilder str_builder(true /*preserve_spaces*/);
+      str_builder.Append(xml_attr->value);
+
       if (!options_.keep_raw_values) {
-        str_builder.Append(xml_attr->value);
         raw_value = str_builder.ToString();
       }
 
diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp
index f1e903f..a57e317 100644
--- a/tools/aapt2/flatten/XmlFlattener_test.cpp
+++ b/tools/aapt2/flatten/XmlFlattener_test.cpp
@@ -23,7 +23,13 @@
 #include "util/BigBuffer.h"
 #include "util/Util.h"
 
-using android::StringPiece16;
+using ::aapt::test::StrEq;
+using ::android::StringPiece16;
+using ::testing::Eq;
+using ::testing::Ge;
+using ::testing::IsNull;
+using ::testing::Ne;
+using ::testing::NotNull;
 
 namespace aapt {
 
@@ -72,163 +78,138 @@
 };
 
 TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-            <View xmlns:test="http://com.test"
-                  attr="hey">
-              <Layout test:hello="hi" />
-              <Layout>Some text\\</Layout>
-            </View>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <View xmlns:test="http://com.test" attr="hey">
+          <Layout test:hello="hi" />
+          <Layout>Some text\\</Layout>
+      </View>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
-
-  ASSERT_EQ(android::ResXMLTree::START_NAMESPACE, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_NAMESPACE));
 
   size_t len;
-  const char16_t* namespace_prefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(u"test"), StringPiece16(namespace_prefix, len));
+  EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"test"));
+  EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://com.test"));
 
-  const char16_t* namespace_uri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(u"http://com.test"), StringPiece16(namespace_uri, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"View"));
 
-  ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next());
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeNamespace(0, &len), IsNull());
+  EXPECT_THAT(tree.getAttributeName(0, &len), StrEq(u"attr"));
 
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  const char16_t* tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"View"), StringPiece16(tag_name, len));
+  const StringPiece16 kAttr(u"attr");
+  EXPECT_THAT(tree.indexOfAttribute(nullptr, 0, kAttr.data(), kAttr.size()), Eq(0));
 
-  ASSERT_EQ(1u, tree.getAttributeCount());
-  ASSERT_EQ(nullptr, tree.getAttributeNamespace(0, &len));
-  const char16_t* attr_name = tree.getAttributeName(0, &len);
-  EXPECT_EQ(StringPiece16(u"attr"), StringPiece16(attr_name, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout"));
 
-  EXPECT_EQ(0, tree.indexOfAttribute(nullptr, 0, u"attr", StringPiece16(u"attr").size()));
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeNamespace(0, &len), StrEq(u"http://com.test"));
+  EXPECT_THAT(tree.getAttributeName(0, &len), StrEq(u"hello"));
 
-  ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
 
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout"));
+  ASSERT_THAT(tree.getAttributeCount(), Eq(0u));
 
-  ASSERT_EQ(1u, tree.getAttributeCount());
-  const char16_t* attr_namespace = tree.getAttributeNamespace(0, &len);
-  EXPECT_EQ(StringPiece16(u"http://com.test"), StringPiece16(attr_namespace, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"Some text\\"));
 
-  attr_name = tree.getAttributeName(0, &len);
-  EXPECT_EQ(StringPiece16(u"hello"), StringPiece16(attr_name, len));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"Layout"));
 
-  ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next());
-  ASSERT_EQ(android::ResXMLTree::START_TAG, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"View"));
 
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len));
-  ASSERT_EQ(0u, tree.getAttributeCount());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_NAMESPACE));
+  EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"test"));
+  EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://com.test"));
 
-  ASSERT_EQ(android::ResXMLTree::TEXT, tree.next());
-  const char16_t* text = tree.getText(&len);
-  EXPECT_EQ(StringPiece16(u"Some text\\"), StringPiece16(text, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next());
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"Layout"), StringPiece16(tag_name, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_TAG, tree.next());
-  ASSERT_EQ(nullptr, tree.getElementNamespace(&len));
-  tag_name = tree.getElementName(&len);
-  EXPECT_EQ(StringPiece16(u"View"), StringPiece16(tag_name, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_NAMESPACE, tree.next());
-  namespace_prefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(u"test"), StringPiece16(namespace_prefix, len));
-
-  namespace_uri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(u"http://com.test"), StringPiece16(namespace_uri, len));
-
-  ASSERT_EQ(android::ResXMLTree::END_DOCUMENT, tree.next());
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_DOCUMENT));
 }
 
 TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-            <View xmlns:tools="http://schemas.android.com/tools"
-                xmlns:foo="http://schemas.android.com/foo"
-                foo:bar="Foo"
-                tools:ignore="MissingTranslation"/>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <View xmlns:tools="http://schemas.android.com/tools"
+          xmlns:foo="http://schemas.android.com/foo"
+          foo:bar="Foo"
+          tools:ignore="MissingTranslation"/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
-
-  ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE);
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_NAMESPACE));
 
   size_t len;
-  const char16_t* namespace_prefix = tree.getNamespacePrefix(&len);
-  EXPECT_EQ(StringPiece16(namespace_prefix, len), u"foo");
+  EXPECT_THAT(tree.getNamespacePrefix(&len), StrEq(u"foo"));
+  EXPECT_THAT(tree.getNamespaceUri(&len), StrEq(u"http://schemas.android.com/foo"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
 
-  const char16_t* namespace_uri = tree.getNamespaceUri(&len);
-  ASSERT_EQ(StringPiece16(namespace_uri, len),
-            u"http://schemas.android.com/foo");
-
-  ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG);
-
-  EXPECT_EQ(tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"),
-            android::NAME_NOT_FOUND);
-  EXPECT_GE(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), 0);
+  EXPECT_THAT(tree.indexOfAttribute("http://schemas.android.com/tools", "ignore"),
+              Eq(android::NAME_NOT_FOUND));
+  EXPECT_THAT(tree.indexOfAttribute("http://schemas.android.com/foo", "bar"), Ge(0));
 }
 
 TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-            <View xmlns:android="http://schemas.android.com/apk/res/android"
-                  android:id="@id/id"
-                  class="str"
-                  style="@id/id"/>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <View xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@id/id"
+          class="str"
+          style="@id/id"/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
-  EXPECT_EQ(tree.indexOfClass(), 0);
-  EXPECT_EQ(tree.indexOfStyle(), 1);
+  EXPECT_THAT(tree.indexOfClass(), Eq(0));
+  EXPECT_THAT(tree.indexOfStyle(), Eq(1));
 }
 
 // The device ResXMLParser in libandroidfw differentiates between empty namespace and null
 // namespace.
 TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom("<View package=\"android\"/>");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<View package="android"/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   const StringPiece16 kPackage = u"package";
-  EXPECT_GE(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), 0);
+  EXPECT_THAT(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), Ge(0));
 }
 
 TEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom("<View package=\"\"/>");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<View package=""/>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   const StringPiece16 kPackage = u"package";
   ssize_t idx = tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size());
-  ASSERT_GE(idx, 0);
+  ASSERT_THAT(idx, Ge(0));
 
   size_t len;
-  EXPECT_NE(nullptr, tree.getAttributeStringValue(idx, &len));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), NotNull());
 }
 
 TEST_F(XmlFlattenerTest, FlattenNonStandardPackageId) {
@@ -236,11 +217,11 @@
   context_->SetPackageId(0x80);
   context_->SetNameManglerPolicy({"com.app.test.feature"});
 
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"EOF(
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"(
       <View xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto"
             android:id="@id/foo"
-            app:foo="@id/foo" />)EOF");
+            app:foo="@id/foo" />)");
 
   XmlReferenceLinker linker;
   ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
@@ -253,59 +234,57 @@
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(android::ResXMLTree::BAD_DOCUMENT, tree.getEventType());
-    ASSERT_NE(android::ResXMLTree::END_DOCUMENT, tree.getEventType());
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   ssize_t idx;
 
   idx = tree.indexOfAttribute(xml::kSchemaAndroid, "id");
-  ASSERT_GE(idx, 0);
-  EXPECT_EQ(idx, tree.indexOfID());
-  EXPECT_EQ(ResourceId(0x010100d0), ResourceId(tree.getAttributeNameResID(idx)));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.indexOfID(), Eq(idx));
+  EXPECT_THAT(tree.getAttributeNameResID(idx), Eq(0x010100d0u));
 
   idx = tree.indexOfAttribute(xml::kSchemaAuto, "foo");
-  ASSERT_GE(idx, 0);
-  EXPECT_EQ(ResourceId(0x80010000), ResourceId(tree.getAttributeNameResID(idx)));
-  EXPECT_EQ(android::Res_value::TYPE_REFERENCE, tree.getAttributeDataType(idx));
-  EXPECT_EQ(ResourceId(0x80020000), tree.getAttributeData(idx));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeNameResID(idx), Eq(0x80010000u));
+  EXPECT_THAT(tree.getAttributeDataType(idx), Eq(android::Res_value::TYPE_REFERENCE));
+  EXPECT_THAT(tree.getAttributeData(idx), Eq(int32_t(0x80020000)));
 }
 
 TEST_F(XmlFlattenerTest, ProcessEscapedStrings) {
   std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(
-      R"EOF(<element value="\?hello" pattern="\\d{5}">\\d{5}</element>)EOF");
+      R"(<element value="\?hello" pattern="\\d{5}" other="&quot;">\\d{5}</element>)");
 
   android::ResXMLTree tree;
   ASSERT_TRUE(Flatten(doc.get(), &tree));
 
   while (tree.next() != android::ResXMLTree::START_TAG) {
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
-    ASSERT_NE(tree.getEventType(), android::ResXMLTree::END_DOCUMENT);
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
   }
 
   const StringPiece16 kValue = u"value";
   const StringPiece16 kPattern = u"pattern";
+  const StringPiece16 kOther = u"other";
 
   size_t len;
   ssize_t idx;
-  const char16_t* str16;
 
   idx = tree.indexOfAttribute(nullptr, 0, kValue.data(), kValue.size());
-  ASSERT_GE(idx, 0);
-  str16 = tree.getAttributeStringValue(idx, &len);
-  ASSERT_NE(nullptr, str16);
-  EXPECT_EQ(StringPiece16(u"?hello"), StringPiece16(str16, len));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"?hello"));
 
   idx = tree.indexOfAttribute(nullptr, 0, kPattern.data(), kPattern.size());
-  ASSERT_GE(idx, 0);
-  str16 = tree.getAttributeStringValue(idx, &len);
-  ASSERT_NE(nullptr, str16);
-  EXPECT_EQ(StringPiece16(u"\\d{5}"), StringPiece16(str16, len));
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"\\d{5}"));
 
-  ASSERT_EQ(android::ResXMLTree::TEXT, tree.next());
-  str16 = tree.getText(&len);
-  ASSERT_NE(nullptr, str16);
-  EXPECT_EQ(StringPiece16(u"\\d{5}"), StringPiece16(str16, len));
+  idx = tree.indexOfAttribute(nullptr, 0, kOther.data(), kOther.size());
+  ASSERT_THAT(idx, Ge(0));
+  EXPECT_THAT(tree.getAttributeStringValue(idx, &len), StrEq(u"\""));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"\\d{5}"));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index 8c476fa..e128c13 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -10,6 +10,9 @@
 - Fixed issue where Java classes referenced from fragments and menus were not added to
   the set of Proguard keep rules. (bug 62216174)
 - Automatically version XML `<adaptive-icon>` resources to v26. (bug 62316340)
+- Fixed issue where escaped unicode characters would generate malformed UTF-8. (bug 62839202)
+- Fixed issue where apostrophes or quotes used in XML attribute values were ignored.
+  (bug 62840406, 62840718)
 
 ## Version 2.17
 ### `aapt2 ...`
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 11821031..d7b46ca 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -136,6 +136,12 @@
 
 namespace test {
 
+MATCHER_P(StrEq, a,
+          std::string(negation ? "isn't" : "is") + " equal to " +
+              ::testing::PrintToString(android::StringPiece16(a))) {
+  return android::StringPiece16(arg) == a;
+}
+
 MATCHER_P(ValueEq, a,
           std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) {
   return arg.Equals(&a);
diff --git a/tools/aapt2/text/Unicode.cpp b/tools/aapt2/text/Unicode.cpp
new file mode 100644
index 0000000..38ec9c4
--- /dev/null
+++ b/tools/aapt2/text/Unicode.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "text/Unicode.h"
+
+#include <algorithm>
+#include <array>
+
+#include "text/Utf8Iterator.h"
+
+using ::android::StringPiece;
+
+namespace aapt {
+namespace text {
+
+namespace {
+
+struct CharacterProperties {
+  enum : uint32_t {
+    kXidStart = 1 << 0,
+    kXidContinue = 1 << 1,
+  };
+
+  char32_t first_char;
+  char32_t last_char;
+  uint32_t properties;
+};
+
+// Incude the generated data table.
+#include "text/Unicode_data.cpp"
+
+bool CompareCharacterProperties(const CharacterProperties& a, char32_t codepoint) {
+  return a.last_char < codepoint;
+}
+
+uint32_t FindCharacterProperties(char32_t codepoint) {
+  const auto iter_end = sCharacterProperties.end();
+  const auto iter = std::lower_bound(sCharacterProperties.begin(), iter_end, codepoint,
+                                     CompareCharacterProperties);
+  if (iter != iter_end && codepoint >= iter->first_char) {
+    return iter->properties;
+  }
+  return 0u;
+}
+
+}  // namespace
+
+bool IsXidStart(char32_t codepoint) {
+  return FindCharacterProperties(codepoint) & CharacterProperties::kXidStart;
+}
+
+bool IsXidContinue(char32_t codepoint) {
+  return FindCharacterProperties(codepoint) & CharacterProperties::kXidContinue;
+}
+
+bool IsJavaIdentifier(const StringPiece& str) {
+  Utf8Iterator iter(str);
+
+  // Check the first character.
+  if (!iter.HasNext()) {
+    return false;
+  }
+
+  if (!IsXidStart(iter.Next())) {
+    return false;
+  }
+
+  while (iter.HasNext()) {
+    const char32_t codepoint = iter.Next();
+    if (!IsXidContinue(codepoint) && codepoint != U'$') {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool IsValidResourceEntryName(const StringPiece& str) {
+  Utf8Iterator iter(str);
+
+  // Check the first character.
+  if (!iter.HasNext()) {
+    return false;
+  }
+
+  // Resources are allowed to start with '_'
+  const char32_t first_codepoint = iter.Next();
+  if (!IsXidStart(first_codepoint) && first_codepoint != U'_') {
+    return false;
+  }
+
+  while (iter.HasNext()) {
+    const char32_t codepoint = iter.Next();
+    if (!IsXidContinue(codepoint) && codepoint != U'.' && codepoint != U'-') {
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace text
+}  // namespace aapt
diff --git a/tools/aapt2/text/Unicode.h b/tools/aapt2/text/Unicode.h
new file mode 100644
index 0000000..2707187
--- /dev/null
+++ b/tools/aapt2/text/Unicode.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef AAPT_TEXT_UNICODE_H
+#define AAPT_TEXT_UNICODE_H
+
+#include "androidfw/StringPiece.h"
+
+namespace aapt {
+namespace text {
+
+// Returns true if the Unicode codepoint has the XID_Start property, meaning it can be used as the
+// first character of a programming language identifier.
+// http://unicode.org/reports/tr31/#Default_Identifier_Syntax
+//
+// XID_Start is a Unicode Derived Core Property. It is a variation of the ID_Start
+// Derived Core Property, accounting for a few characters that, when normalized, yield valid
+// characters in the ID_Start set.
+bool IsXidStart(char32_t codepoint);
+
+// Returns true if the Unicode codepoint has the XID_Continue property, meaning it can be used in
+// any position of a programming language identifier, except the first.
+// http://unicode.org/reports/tr31/#Default_Identifier_Syntax
+//
+// XID_Continue is a Unicode Derived Core Property. It is a variation of the ID_Continue
+// Derived Core Property, accounting for a few characters that, when normalized, yield valid
+// characters in the ID_Continue set.
+bool IsXidContinue(char32_t codepoint);
+
+// Returns true if the UTF8 string can be used as a Java identifier.
+// NOTE: This does not check against the set of reserved Java keywords.
+bool IsJavaIdentifier(const android::StringPiece& str);
+
+// Returns true if the UTF8 string can be used as the entry name of a resource name.
+// This is the `entry` part of package:type/entry.
+bool IsValidResourceEntryName(const android::StringPiece& str);
+
+}  // namespace text
+}  // namespace aapt
+
+#endif  // AAPT_TEXT_UNICODE_H
diff --git a/tools/aapt2/text/Unicode_data.cpp b/tools/aapt2/text/Unicode_data.cpp
new file mode 100644
index 0000000..96dc57b
--- /dev/null
+++ b/tools/aapt2/text/Unicode_data.cpp
@@ -0,0 +1,629 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+const static std::array<CharacterProperties, 611> sCharacterProperties = {{
+    {0x0030, 0x0039, CharacterProperties::kXidContinue},
+    {0x0041, 0x005a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x005f, 0x005f, CharacterProperties::kXidContinue},
+    {0x0061, 0x007a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x00aa, 0x00aa, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x00b5, 0x00b5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x00b7, 0x00b7, CharacterProperties::kXidContinue},
+    {0x00ba, 0x00ba, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x00c0, 0x00d6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x00d8, 0x00f6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x00f8, 0x02c1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x02c6, 0x02d1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x02e0, 0x02e4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x02ec, 0x02ec, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x02ee, 0x02ee, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0300, 0x036f, CharacterProperties::kXidContinue},
+    {0x0370, 0x0374, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0376, 0x0377, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x037b, 0x037d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x037f, 0x037f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0386, 0x0386, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0387, 0x0387, CharacterProperties::kXidContinue},
+    {0x0388, 0x038a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x038c, 0x038c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x038e, 0x03a1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x03a3, 0x03f5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x03f7, 0x0481, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0483, 0x0487, CharacterProperties::kXidContinue},
+    {0x048a, 0x052f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0531, 0x0556, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0559, 0x0559, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0561, 0x0587, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0591, 0x05bd, CharacterProperties::kXidContinue},
+    {0x05bf, 0x05bf, CharacterProperties::kXidContinue},
+    {0x05c1, 0x05c2, CharacterProperties::kXidContinue},
+    {0x05c4, 0x05c5, CharacterProperties::kXidContinue},
+    {0x05c7, 0x05c7, CharacterProperties::kXidContinue},
+    {0x05d0, 0x05ea, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x05f0, 0x05f2, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0610, 0x061a, CharacterProperties::kXidContinue},
+    {0x0620, 0x064a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x064b, 0x0669, CharacterProperties::kXidContinue},
+    {0x066e, 0x066f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0670, 0x0670, CharacterProperties::kXidContinue},
+    {0x0671, 0x06d3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x06d5, 0x06d5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x06d6, 0x06dc, CharacterProperties::kXidContinue},
+    {0x06df, 0x06e4, CharacterProperties::kXidContinue},
+    {0x06e5, 0x06e6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x06e7, 0x06e8, CharacterProperties::kXidContinue},
+    {0x06ea, 0x06ed, CharacterProperties::kXidContinue},
+    {0x06ee, 0x06ef, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x06f0, 0x06f9, CharacterProperties::kXidContinue},
+    {0x06fa, 0x06fc, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x06ff, 0x06ff, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0710, 0x0710, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0711, 0x0711, CharacterProperties::kXidContinue},
+    {0x0712, 0x072f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0730, 0x074a, CharacterProperties::kXidContinue},
+    {0x074d, 0x07a5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x07a6, 0x07b0, CharacterProperties::kXidContinue},
+    {0x07b1, 0x07b1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x07c0, 0x07c9, CharacterProperties::kXidContinue},
+    {0x07ca, 0x07ea, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x07eb, 0x07f3, CharacterProperties::kXidContinue},
+    {0x07f4, 0x07f5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x07fa, 0x07fa, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0800, 0x0815, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0816, 0x0819, CharacterProperties::kXidContinue},
+    {0x081a, 0x081a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x081b, 0x0823, CharacterProperties::kXidContinue},
+    {0x0824, 0x0824, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0825, 0x0827, CharacterProperties::kXidContinue},
+    {0x0828, 0x0828, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0829, 0x082d, CharacterProperties::kXidContinue},
+    {0x0840, 0x0858, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0859, 0x085b, CharacterProperties::kXidContinue},
+    {0x08a0, 0x08b4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x08b6, 0x08bd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x08d4, 0x08e1, CharacterProperties::kXidContinue},
+    {0x08e3, 0x0903, CharacterProperties::kXidContinue},
+    {0x0904, 0x0939, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x093a, 0x093c, CharacterProperties::kXidContinue},
+    {0x093d, 0x093d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x093e, 0x094f, CharacterProperties::kXidContinue},
+    {0x0950, 0x0950, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0951, 0x0957, CharacterProperties::kXidContinue},
+    {0x0958, 0x0961, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0962, 0x0963, CharacterProperties::kXidContinue},
+    {0x0966, 0x096f, CharacterProperties::kXidContinue},
+    {0x0971, 0x0980, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0981, 0x0983, CharacterProperties::kXidContinue},
+    {0x0985, 0x098c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x098f, 0x0990, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0993, 0x09a8, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09aa, 0x09b0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09b2, 0x09b2, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09b6, 0x09b9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09bc, 0x09bc, CharacterProperties::kXidContinue},
+    {0x09bd, 0x09bd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09be, 0x09c4, CharacterProperties::kXidContinue},
+    {0x09c7, 0x09c8, CharacterProperties::kXidContinue},
+    {0x09cb, 0x09cd, CharacterProperties::kXidContinue},
+    {0x09ce, 0x09ce, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09d7, 0x09d7, CharacterProperties::kXidContinue},
+    {0x09dc, 0x09dd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09df, 0x09e1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x09e2, 0x09e3, CharacterProperties::kXidContinue},
+    {0x09e6, 0x09ef, CharacterProperties::kXidContinue},
+    {0x09f0, 0x09f1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a01, 0x0a03, CharacterProperties::kXidContinue},
+    {0x0a05, 0x0a0a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a0f, 0x0a10, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a13, 0x0a28, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a2a, 0x0a30, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a32, 0x0a33, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a35, 0x0a36, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a38, 0x0a39, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a3c, 0x0a3c, CharacterProperties::kXidContinue},
+    {0x0a3e, 0x0a42, CharacterProperties::kXidContinue},
+    {0x0a47, 0x0a48, CharacterProperties::kXidContinue},
+    {0x0a4b, 0x0a4d, CharacterProperties::kXidContinue},
+    {0x0a51, 0x0a51, CharacterProperties::kXidContinue},
+    {0x0a59, 0x0a5c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a5e, 0x0a5e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a66, 0x0a71, CharacterProperties::kXidContinue},
+    {0x0a72, 0x0a74, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a75, 0x0a75, CharacterProperties::kXidContinue},
+    {0x0a81, 0x0a83, CharacterProperties::kXidContinue},
+    {0x0a85, 0x0a8d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a8f, 0x0a91, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0a93, 0x0aa8, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0aaa, 0x0ab0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ab2, 0x0ab3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ab5, 0x0ab9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0abc, 0x0abc, CharacterProperties::kXidContinue},
+    {0x0abd, 0x0abd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0abe, 0x0ac5, CharacterProperties::kXidContinue},
+    {0x0ac7, 0x0ac9, CharacterProperties::kXidContinue},
+    {0x0acb, 0x0acd, CharacterProperties::kXidContinue},
+    {0x0ad0, 0x0ad0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ae0, 0x0ae1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ae2, 0x0ae3, CharacterProperties::kXidContinue},
+    {0x0ae6, 0x0aef, CharacterProperties::kXidContinue},
+    {0x0af9, 0x0af9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b01, 0x0b03, CharacterProperties::kXidContinue},
+    {0x0b05, 0x0b0c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b0f, 0x0b10, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b13, 0x0b28, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b2a, 0x0b30, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b32, 0x0b33, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b35, 0x0b39, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b3c, 0x0b3c, CharacterProperties::kXidContinue},
+    {0x0b3d, 0x0b3d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b3e, 0x0b44, CharacterProperties::kXidContinue},
+    {0x0b47, 0x0b48, CharacterProperties::kXidContinue},
+    {0x0b4b, 0x0b4d, CharacterProperties::kXidContinue},
+    {0x0b56, 0x0b57, CharacterProperties::kXidContinue},
+    {0x0b5c, 0x0b5d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b5f, 0x0b61, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b62, 0x0b63, CharacterProperties::kXidContinue},
+    {0x0b66, 0x0b6f, CharacterProperties::kXidContinue},
+    {0x0b71, 0x0b71, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b82, 0x0b82, CharacterProperties::kXidContinue},
+    {0x0b83, 0x0b83, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b85, 0x0b8a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b8e, 0x0b90, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b92, 0x0b95, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b99, 0x0b9a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b9c, 0x0b9c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0b9e, 0x0b9f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ba3, 0x0ba4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ba8, 0x0baa, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0bae, 0x0bb9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0bbe, 0x0bc2, CharacterProperties::kXidContinue},
+    {0x0bc6, 0x0bc8, CharacterProperties::kXidContinue},
+    {0x0bca, 0x0bcd, CharacterProperties::kXidContinue},
+    {0x0bd0, 0x0bd0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0bd7, 0x0bd7, CharacterProperties::kXidContinue},
+    {0x0be6, 0x0bef, CharacterProperties::kXidContinue},
+    {0x0c00, 0x0c03, CharacterProperties::kXidContinue},
+    {0x0c05, 0x0c0c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c0e, 0x0c10, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c12, 0x0c28, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c2a, 0x0c39, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c3d, 0x0c3d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c3e, 0x0c44, CharacterProperties::kXidContinue},
+    {0x0c46, 0x0c48, CharacterProperties::kXidContinue},
+    {0x0c4a, 0x0c4d, CharacterProperties::kXidContinue},
+    {0x0c55, 0x0c56, CharacterProperties::kXidContinue},
+    {0x0c58, 0x0c5a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c60, 0x0c61, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c62, 0x0c63, CharacterProperties::kXidContinue},
+    {0x0c66, 0x0c6f, CharacterProperties::kXidContinue},
+    {0x0c80, 0x0c80, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c81, 0x0c83, CharacterProperties::kXidContinue},
+    {0x0c85, 0x0c8c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c8e, 0x0c90, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0c92, 0x0ca8, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0caa, 0x0cb3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0cb5, 0x0cb9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0cbc, 0x0cbc, CharacterProperties::kXidContinue},
+    {0x0cbd, 0x0cbd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0cbe, 0x0cc4, CharacterProperties::kXidContinue},
+    {0x0cc6, 0x0cc8, CharacterProperties::kXidContinue},
+    {0x0cca, 0x0ccd, CharacterProperties::kXidContinue},
+    {0x0cd5, 0x0cd6, CharacterProperties::kXidContinue},
+    {0x0cde, 0x0cde, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ce0, 0x0ce1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ce2, 0x0ce3, CharacterProperties::kXidContinue},
+    {0x0ce6, 0x0cef, CharacterProperties::kXidContinue},
+    {0x0cf1, 0x0cf2, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d01, 0x0d03, CharacterProperties::kXidContinue},
+    {0x0d05, 0x0d0c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d0e, 0x0d10, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d12, 0x0d3a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d3d, 0x0d3d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d3e, 0x0d44, CharacterProperties::kXidContinue},
+    {0x0d46, 0x0d48, CharacterProperties::kXidContinue},
+    {0x0d4a, 0x0d4d, CharacterProperties::kXidContinue},
+    {0x0d4e, 0x0d4e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d54, 0x0d56, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d57, 0x0d57, CharacterProperties::kXidContinue},
+    {0x0d5f, 0x0d61, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d62, 0x0d63, CharacterProperties::kXidContinue},
+    {0x0d66, 0x0d6f, CharacterProperties::kXidContinue},
+    {0x0d7a, 0x0d7f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d82, 0x0d83, CharacterProperties::kXidContinue},
+    {0x0d85, 0x0d96, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0d9a, 0x0db1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0db3, 0x0dbb, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0dbd, 0x0dbd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0dc0, 0x0dc6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0dca, 0x0dca, CharacterProperties::kXidContinue},
+    {0x0dcf, 0x0dd4, CharacterProperties::kXidContinue},
+    {0x0dd6, 0x0dd6, CharacterProperties::kXidContinue},
+    {0x0dd8, 0x0ddf, CharacterProperties::kXidContinue},
+    {0x0de6, 0x0def, CharacterProperties::kXidContinue},
+    {0x0df2, 0x0df3, CharacterProperties::kXidContinue},
+    {0x0e01, 0x0e30, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e31, 0x0e31, CharacterProperties::kXidContinue},
+    {0x0e32, 0x0e32, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e33, 0x0e3a, CharacterProperties::kXidContinue},
+    {0x0e40, 0x0e46, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e47, 0x0e4e, CharacterProperties::kXidContinue},
+    {0x0e50, 0x0e59, CharacterProperties::kXidContinue},
+    {0x0e81, 0x0e82, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e84, 0x0e84, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e87, 0x0e88, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e8a, 0x0e8a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e8d, 0x0e8d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e94, 0x0e97, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0e99, 0x0e9f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ea1, 0x0ea3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ea5, 0x0ea5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ea7, 0x0ea7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0eaa, 0x0eab, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ead, 0x0eb0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0eb1, 0x0eb1, CharacterProperties::kXidContinue},
+    {0x0eb2, 0x0eb2, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0eb3, 0x0eb9, CharacterProperties::kXidContinue},
+    {0x0ebb, 0x0ebc, CharacterProperties::kXidContinue},
+    {0x0ebd, 0x0ebd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ec0, 0x0ec4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ec6, 0x0ec6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0ec8, 0x0ecd, CharacterProperties::kXidContinue},
+    {0x0ed0, 0x0ed9, CharacterProperties::kXidContinue},
+    {0x0edc, 0x0edf, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0f00, 0x0f00, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0f18, 0x0f19, CharacterProperties::kXidContinue},
+    {0x0f20, 0x0f29, CharacterProperties::kXidContinue},
+    {0x0f35, 0x0f35, CharacterProperties::kXidContinue},
+    {0x0f37, 0x0f37, CharacterProperties::kXidContinue},
+    {0x0f39, 0x0f39, CharacterProperties::kXidContinue},
+    {0x0f3e, 0x0f3f, CharacterProperties::kXidContinue},
+    {0x0f40, 0x0f47, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0f49, 0x0f6c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0f71, 0x0f84, CharacterProperties::kXidContinue},
+    {0x0f86, 0x0f87, CharacterProperties::kXidContinue},
+    {0x0f88, 0x0f8c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x0f8d, 0x0f97, CharacterProperties::kXidContinue},
+    {0x0f99, 0x0fbc, CharacterProperties::kXidContinue},
+    {0x0fc6, 0x0fc6, CharacterProperties::kXidContinue},
+    {0x1000, 0x102a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x102b, 0x103e, CharacterProperties::kXidContinue},
+    {0x103f, 0x103f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1040, 0x1049, CharacterProperties::kXidContinue},
+    {0x1050, 0x1055, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1056, 0x1059, CharacterProperties::kXidContinue},
+    {0x105a, 0x105d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x105e, 0x1060, CharacterProperties::kXidContinue},
+    {0x1061, 0x1061, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1062, 0x1064, CharacterProperties::kXidContinue},
+    {0x1065, 0x1066, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1067, 0x106d, CharacterProperties::kXidContinue},
+    {0x106e, 0x1070, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1071, 0x1074, CharacterProperties::kXidContinue},
+    {0x1075, 0x1081, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1082, 0x108d, CharacterProperties::kXidContinue},
+    {0x108e, 0x108e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x108f, 0x109d, CharacterProperties::kXidContinue},
+    {0x10a0, 0x10c5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x10c7, 0x10c7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x10cd, 0x10cd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x10d0, 0x10fa, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x10fc, 0x1248, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x124a, 0x124d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1250, 0x1256, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1258, 0x1258, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x125a, 0x125d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1260, 0x1288, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x128a, 0x128d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1290, 0x12b0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x12b2, 0x12b5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x12b8, 0x12be, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x12c0, 0x12c0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x12c2, 0x12c5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x12c8, 0x12d6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x12d8, 0x1310, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1312, 0x1315, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1318, 0x135a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x135d, 0x135f, CharacterProperties::kXidContinue},
+    {0x1369, 0x1371, CharacterProperties::kXidContinue},
+    {0x1380, 0x138f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x13a0, 0x13f5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x13f8, 0x13fd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1401, 0x166c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x166f, 0x167f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1681, 0x169a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x16a0, 0x16ea, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x16ee, 0x16f8, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1700, 0x170c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x170e, 0x1711, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1712, 0x1714, CharacterProperties::kXidContinue},
+    {0x1720, 0x1731, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1732, 0x1734, CharacterProperties::kXidContinue},
+    {0x1740, 0x1751, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1752, 0x1753, CharacterProperties::kXidContinue},
+    {0x1760, 0x176c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x176e, 0x1770, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1772, 0x1773, CharacterProperties::kXidContinue},
+    {0x1780, 0x17b3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x17b4, 0x17d3, CharacterProperties::kXidContinue},
+    {0x17d7, 0x17d7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x17dc, 0x17dc, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x17dd, 0x17dd, CharacterProperties::kXidContinue},
+    {0x17e0, 0x17e9, CharacterProperties::kXidContinue},
+    {0x180b, 0x180d, CharacterProperties::kXidContinue},
+    {0x1810, 0x1819, CharacterProperties::kXidContinue},
+    {0x1820, 0x1877, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1880, 0x18a8, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x18a9, 0x18a9, CharacterProperties::kXidContinue},
+    {0x18aa, 0x18aa, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x18b0, 0x18f5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1900, 0x191e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1920, 0x192b, CharacterProperties::kXidContinue},
+    {0x1930, 0x193b, CharacterProperties::kXidContinue},
+    {0x1946, 0x194f, CharacterProperties::kXidContinue},
+    {0x1950, 0x196d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1970, 0x1974, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1980, 0x19ab, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x19b0, 0x19c9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x19d0, 0x19da, CharacterProperties::kXidContinue},
+    {0x1a00, 0x1a16, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1a17, 0x1a1b, CharacterProperties::kXidContinue},
+    {0x1a20, 0x1a54, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1a55, 0x1a5e, CharacterProperties::kXidContinue},
+    {0x1a60, 0x1a7c, CharacterProperties::kXidContinue},
+    {0x1a7f, 0x1a89, CharacterProperties::kXidContinue},
+    {0x1a90, 0x1a99, CharacterProperties::kXidContinue},
+    {0x1aa7, 0x1aa7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1ab0, 0x1abd, CharacterProperties::kXidContinue},
+    {0x1b00, 0x1b04, CharacterProperties::kXidContinue},
+    {0x1b05, 0x1b33, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1b34, 0x1b44, CharacterProperties::kXidContinue},
+    {0x1b45, 0x1b4b, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1b50, 0x1b59, CharacterProperties::kXidContinue},
+    {0x1b6b, 0x1b73, CharacterProperties::kXidContinue},
+    {0x1b80, 0x1b82, CharacterProperties::kXidContinue},
+    {0x1b83, 0x1ba0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1ba1, 0x1bad, CharacterProperties::kXidContinue},
+    {0x1bae, 0x1baf, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1bb0, 0x1bb9, CharacterProperties::kXidContinue},
+    {0x1bba, 0x1be5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1be6, 0x1bf3, CharacterProperties::kXidContinue},
+    {0x1c00, 0x1c23, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1c24, 0x1c37, CharacterProperties::kXidContinue},
+    {0x1c40, 0x1c49, CharacterProperties::kXidContinue},
+    {0x1c4d, 0x1c4f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1c50, 0x1c59, CharacterProperties::kXidContinue},
+    {0x1c5a, 0x1c7d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1c80, 0x1c88, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1cd0, 0x1cd2, CharacterProperties::kXidContinue},
+    {0x1cd4, 0x1ce8, CharacterProperties::kXidContinue},
+    {0x1ce9, 0x1cec, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1ced, 0x1ced, CharacterProperties::kXidContinue},
+    {0x1cee, 0x1cf1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1cf2, 0x1cf4, CharacterProperties::kXidContinue},
+    {0x1cf5, 0x1cf6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1cf8, 0x1cf9, CharacterProperties::kXidContinue},
+    {0x1d00, 0x1dbf, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1dc0, 0x1df5, CharacterProperties::kXidContinue},
+    {0x1dfb, 0x1dff, CharacterProperties::kXidContinue},
+    {0x1e00, 0x1f15, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f18, 0x1f1d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f20, 0x1f45, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f48, 0x1f4d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f50, 0x1f57, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f59, 0x1f59, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f5b, 0x1f5b, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f5d, 0x1f5d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f5f, 0x1f7d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1f80, 0x1fb4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1fb6, 0x1fbc, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1fbe, 0x1fbe, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1fc2, 0x1fc4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1fc6, 0x1fcc, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1fd0, 0x1fd3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1fd6, 0x1fdb, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1fe0, 0x1fec, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1ff2, 0x1ff4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x1ff6, 0x1ffc, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x203f, 0x2040, CharacterProperties::kXidContinue},
+    {0x2054, 0x2054, CharacterProperties::kXidContinue},
+    {0x2071, 0x2071, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x207f, 0x207f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2090, 0x209c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x20d0, 0x20dc, CharacterProperties::kXidContinue},
+    {0x20e1, 0x20e1, CharacterProperties::kXidContinue},
+    {0x20e5, 0x20f0, CharacterProperties::kXidContinue},
+    {0x2102, 0x2102, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2107, 0x2107, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x210a, 0x2113, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2115, 0x2115, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2118, 0x211d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2124, 0x2124, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2126, 0x2126, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2128, 0x2128, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x212a, 0x2139, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x213c, 0x213f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2145, 0x2149, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x214e, 0x214e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2160, 0x2188, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2c00, 0x2c2e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2c30, 0x2c5e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2c60, 0x2ce4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2ceb, 0x2cee, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2cef, 0x2cf1, CharacterProperties::kXidContinue},
+    {0x2cf2, 0x2cf3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2d00, 0x2d25, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2d27, 0x2d27, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2d2d, 0x2d2d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2d30, 0x2d67, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2d6f, 0x2d6f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2d7f, 0x2d7f, CharacterProperties::kXidContinue},
+    {0x2d80, 0x2d96, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2da0, 0x2da6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2da8, 0x2dae, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2db0, 0x2db6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2db8, 0x2dbe, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2dc0, 0x2dc6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2dc8, 0x2dce, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2dd0, 0x2dd6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2dd8, 0x2dde, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x2de0, 0x2dff, CharacterProperties::kXidContinue},
+    {0x3005, 0x3007, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x3021, 0x3029, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x302a, 0x302f, CharacterProperties::kXidContinue},
+    {0x3031, 0x3035, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x3038, 0x303c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x3041, 0x3096, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x3099, 0x309a, CharacterProperties::kXidContinue},
+    {0x309d, 0x309f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x30a1, 0x30fa, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x30fc, 0x30ff, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x3105, 0x312d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x3131, 0x318e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x31a0, 0x31ba, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x31f0, 0x31ff, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x3400, 0x4db5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0x4e00, 0x9fd5, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa000, 0xa48c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa4d0, 0xa4fd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa500, 0xa60c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa610, 0xa61f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa620, 0xa629, CharacterProperties::kXidContinue},
+    {0xa62a, 0xa62b, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa640, 0xa66e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa66f, 0xa66f, CharacterProperties::kXidContinue},
+    {0xa674, 0xa67d, CharacterProperties::kXidContinue},
+    {0xa67f, 0xa69d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa69e, 0xa69f, CharacterProperties::kXidContinue},
+    {0xa6a0, 0xa6ef, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa6f0, 0xa6f1, CharacterProperties::kXidContinue},
+    {0xa717, 0xa71f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa722, 0xa788, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa78b, 0xa7ae, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa7b0, 0xa7b7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa7f7, 0xa801, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa802, 0xa802, CharacterProperties::kXidContinue},
+    {0xa803, 0xa805, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa806, 0xa806, CharacterProperties::kXidContinue},
+    {0xa807, 0xa80a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa80b, 0xa80b, CharacterProperties::kXidContinue},
+    {0xa80c, 0xa822, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa823, 0xa827, CharacterProperties::kXidContinue},
+    {0xa840, 0xa873, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa880, 0xa881, CharacterProperties::kXidContinue},
+    {0xa882, 0xa8b3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa8b4, 0xa8c5, CharacterProperties::kXidContinue},
+    {0xa8d0, 0xa8d9, CharacterProperties::kXidContinue},
+    {0xa8e0, 0xa8f1, CharacterProperties::kXidContinue},
+    {0xa8f2, 0xa8f7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa8fb, 0xa8fb, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa8fd, 0xa8fd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa900, 0xa909, CharacterProperties::kXidContinue},
+    {0xa90a, 0xa925, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa926, 0xa92d, CharacterProperties::kXidContinue},
+    {0xa930, 0xa946, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa947, 0xa953, CharacterProperties::kXidContinue},
+    {0xa960, 0xa97c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa980, 0xa983, CharacterProperties::kXidContinue},
+    {0xa984, 0xa9b2, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa9b3, 0xa9c0, CharacterProperties::kXidContinue},
+    {0xa9cf, 0xa9cf, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa9d0, 0xa9d9, CharacterProperties::kXidContinue},
+    {0xa9e0, 0xa9e4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa9e5, 0xa9e5, CharacterProperties::kXidContinue},
+    {0xa9e6, 0xa9ef, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xa9f0, 0xa9f9, CharacterProperties::kXidContinue},
+    {0xa9fa, 0xa9fe, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaa00, 0xaa28, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaa29, 0xaa36, CharacterProperties::kXidContinue},
+    {0xaa40, 0xaa42, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaa43, 0xaa43, CharacterProperties::kXidContinue},
+    {0xaa44, 0xaa4b, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaa4c, 0xaa4d, CharacterProperties::kXidContinue},
+    {0xaa50, 0xaa59, CharacterProperties::kXidContinue},
+    {0xaa60, 0xaa76, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaa7a, 0xaa7a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaa7b, 0xaa7d, CharacterProperties::kXidContinue},
+    {0xaa7e, 0xaaaf, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaab0, 0xaab0, CharacterProperties::kXidContinue},
+    {0xaab1, 0xaab1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaab2, 0xaab4, CharacterProperties::kXidContinue},
+    {0xaab5, 0xaab6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaab7, 0xaab8, CharacterProperties::kXidContinue},
+    {0xaab9, 0xaabd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaabe, 0xaabf, CharacterProperties::kXidContinue},
+    {0xaac0, 0xaac0, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaac1, 0xaac1, CharacterProperties::kXidContinue},
+    {0xaac2, 0xaac2, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaadb, 0xaadd, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaae0, 0xaaea, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaaeb, 0xaaef, CharacterProperties::kXidContinue},
+    {0xaaf2, 0xaaf4, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xaaf5, 0xaaf6, CharacterProperties::kXidContinue},
+    {0xab01, 0xab06, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xab09, 0xab0e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xab11, 0xab16, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xab20, 0xab26, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xab28, 0xab2e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xab30, 0xab5a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xab5c, 0xab65, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xab70, 0xabe2, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xabe3, 0xabea, CharacterProperties::kXidContinue},
+    {0xabec, 0xabed, CharacterProperties::kXidContinue},
+    {0xabf0, 0xabf9, CharacterProperties::kXidContinue},
+    {0xac00, 0xd7a3, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xd7b0, 0xd7c6, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xd7cb, 0xd7fb, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xf900, 0xfa6d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfa70, 0xfad9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb00, 0xfb06, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb13, 0xfb17, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb1d, 0xfb1d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb1e, 0xfb1e, CharacterProperties::kXidContinue},
+    {0xfb1f, 0xfb28, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb2a, 0xfb36, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb38, 0xfb3c, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb3e, 0xfb3e, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb40, 0xfb41, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb43, 0xfb44, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfb46, 0xfbb1, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfbd3, 0xfc5d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfc64, 0xfd3d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfd50, 0xfd8f, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfd92, 0xfdc7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfdf0, 0xfdf9, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfe00, 0xfe0f, CharacterProperties::kXidContinue},
+    {0xfe20, 0xfe2f, CharacterProperties::kXidContinue},
+    {0xfe33, 0xfe34, CharacterProperties::kXidContinue},
+    {0xfe4d, 0xfe4f, CharacterProperties::kXidContinue},
+    {0xfe71, 0xfe71, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfe73, 0xfe73, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfe77, 0xfe77, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfe79, 0xfe79, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfe7b, 0xfe7b, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfe7d, 0xfe7d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xfe7f, 0xfefc, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xff10, 0xff19, CharacterProperties::kXidContinue},
+    {0xff21, 0xff3a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xff3f, 0xff3f, CharacterProperties::kXidContinue},
+    {0xff41, 0xff5a, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xff66, 0xff9d, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xff9e, 0xff9f, CharacterProperties::kXidContinue},
+    {0xffa0, 0xffbe, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xffc2, 0xffc7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xffca, 0xffcf, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xffd2, 0xffd7, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+    {0xffda, 0xffdc, CharacterProperties::kXidStart | CharacterProperties::kXidContinue},
+}};
diff --git a/tools/aapt2/text/Unicode_test.cpp b/tools/aapt2/text/Unicode_test.cpp
new file mode 100644
index 0000000..d47fb28
--- /dev/null
+++ b/tools/aapt2/text/Unicode_test.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "text/Unicode.h"
+
+#include "test/Test.h"
+
+using ::testing::Each;
+using ::testing::Eq;
+using ::testing::ResultOf;
+
+namespace aapt {
+namespace text {
+
+TEST(UnicodeTest, IsXidStart) {
+  std::u32string valid_input = U"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZˮø";
+  EXPECT_THAT(valid_input, Each(ResultOf(IsXidStart, Eq(true))));
+
+  std::u32string invalid_input = U"$;\'/<>+=-.{}[]()\\|?@#%^&*!~`\",1234567890_";
+  EXPECT_THAT(invalid_input, Each(ResultOf(IsXidStart, Eq(false))));
+}
+
+TEST(UnicodeTest, IsXidContinue) {
+  std::u32string valid_input = U"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_ˮø";
+  EXPECT_THAT(valid_input, Each(ResultOf(IsXidContinue, Eq(true))));
+
+  std::u32string invalid_input = U"$;\'/<>+=-.{}[]()\\|?@#%^&*!~`\",";
+  EXPECT_THAT(invalid_input, Each(ResultOf(IsXidContinue, Eq(false))));
+}
+
+TEST(UnicodeTest, IsJavaIdentifier) {
+  EXPECT_TRUE(IsJavaIdentifier("FøøBar_12"));
+  EXPECT_TRUE(IsJavaIdentifier("Føø$Bar"));
+
+  EXPECT_FALSE(IsJavaIdentifier("12FøøBar"));
+  EXPECT_FALSE(IsJavaIdentifier("_FøøBar"));
+  EXPECT_FALSE(IsJavaIdentifier("$Føø$Bar"));
+}
+
+TEST(UnicodeTest, IsValidResourceEntryName) {
+  EXPECT_TRUE(IsJavaIdentifier("FøøBar"));
+  EXPECT_TRUE(IsValidResourceEntryName("FøøBar_12"));
+  EXPECT_TRUE(IsValidResourceEntryName("Føø.Bar"));
+  EXPECT_TRUE(IsValidResourceEntryName("Føø-Bar"));
+  EXPECT_TRUE(IsValidResourceEntryName("_FøøBar"));
+
+  EXPECT_FALSE(IsValidResourceEntryName("12FøøBar"));
+  EXPECT_FALSE(IsValidResourceEntryName("Føø$Bar"));
+  EXPECT_FALSE(IsValidResourceEntryName("Føø/Bar"));
+  EXPECT_FALSE(IsValidResourceEntryName("Føø:Bar"));
+  EXPECT_FALSE(IsValidResourceEntryName("Føø;Bar"));
+}
+
+}  // namespace text
+}  // namespace aapt
diff --git a/tools/aapt2/text/Utf8Iterator.cpp b/tools/aapt2/text/Utf8Iterator.cpp
new file mode 100644
index 0000000..0d43353
--- /dev/null
+++ b/tools/aapt2/text/Utf8Iterator.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "text/Utf8Iterator.h"
+
+#include "android-base/logging.h"
+#include "utils/Unicode.h"
+
+using ::android::StringPiece;
+
+namespace aapt {
+namespace text {
+
+Utf8Iterator::Utf8Iterator(const StringPiece& str)
+    : str_(str), next_pos_(0), current_codepoint_(0) {
+  DoNext();
+}
+
+void Utf8Iterator::DoNext() {
+  size_t next_pos = 0u;
+  int32_t result = utf32_from_utf8_at(str_.data(), str_.size(), next_pos_, &next_pos);
+  if (result == -1) {
+    current_codepoint_ = 0u;
+  } else {
+    current_codepoint_ = static_cast<char32_t>(result);
+    next_pos_ = next_pos;
+  }
+}
+
+bool Utf8Iterator::HasNext() const {
+  return current_codepoint_ != 0;
+}
+
+void Utf8Iterator::Skip(int amount) {
+  while (amount > 0 && HasNext()) {
+    Next();
+    --amount;
+  }
+}
+
+char32_t Utf8Iterator::Next() {
+  CHECK(HasNext()) << "Next() called after iterator exhausted";
+  char32_t result = current_codepoint_;
+  DoNext();
+  return result;
+}
+
+}  // namespace text
+}  // namespace aapt
diff --git a/tools/aapt2/text/Utf8Iterator.h b/tools/aapt2/text/Utf8Iterator.h
new file mode 100644
index 0000000..6923957
--- /dev/null
+++ b/tools/aapt2/text/Utf8Iterator.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef AAPT_TEXT_UTF8ITERATOR_H
+#define AAPT_TEXT_UTF8ITERATOR_H
+
+#include "android-base/macros.h"
+#include "androidfw/StringPiece.h"
+
+namespace aapt {
+namespace text {
+
+class Utf8Iterator {
+ public:
+  explicit Utf8Iterator(const android::StringPiece& str);
+
+  bool HasNext() const;
+
+  void Skip(int amount);
+
+  char32_t Next();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Utf8Iterator);
+
+  void DoNext();
+
+  android::StringPiece str_;
+  size_t next_pos_;
+  char32_t current_codepoint_;
+};
+
+}  // namespace text
+}  // namespace aapt
+
+#endif  // AAPT_TEXT_UTF8ITERATOR_H
diff --git a/tools/aapt2/text/Utf8Iterator_test.cpp b/tools/aapt2/text/Utf8Iterator_test.cpp
new file mode 100644
index 0000000..f3111c0
--- /dev/null
+++ b/tools/aapt2/text/Utf8Iterator_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "text/Utf8Iterator.h"
+
+#include "test/Test.h"
+
+using ::testing::Eq;
+
+namespace aapt {
+namespace text {
+
+TEST(Utf8IteratorTest, IteratesOverAscii) {
+  Utf8Iterator iter("hello");
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'h'));
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'e'));
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'l'));
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'l'));
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'o'));
+
+  EXPECT_FALSE(iter.HasNext());
+}
+
+TEST(Utf8IteratorTest, IteratesOverUnicode) {
+  Utf8Iterator iter("Hi there 華勵蓮🍩");
+  iter.Skip(9);
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'華'));
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'勵'));
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'蓮'));
+
+  ASSERT_TRUE(iter.HasNext());
+  EXPECT_THAT(iter.Next(), Eq(U'🍩'));
+
+  EXPECT_FALSE(iter.HasNext());
+}
+
+}  // namespace text
+}  // namespace aapt
diff --git a/tools/aapt2/tools/extract_unicode_properties.py b/tools/aapt2/tools/extract_unicode_properties.py
new file mode 100644
index 0000000..d7e0479
--- /dev/null
+++ b/tools/aapt2/tools/extract_unicode_properties.py
@@ -0,0 +1,98 @@
+#!/bin/env python3
+
+"""Extracts the XID_Start and XID_Continue Derived core properties from the ICU data files
+and emits a std::array<> for binary searching.
+"""
+
+import re
+import sys
+
+CharacterPropertyEnumMap = {
+        1: "CharacterProperties::kXidStart",
+        2: "CharacterProperties::kXidContinue"
+}
+
+class CharacterProperty:
+    def __init__(self, first_char, last_char, prop_type):
+        self.first_char = first_char
+        self.last_char = last_char
+        self.prop_type = prop_type
+
+    def key(self):
+        return self.first_char
+
+    def merge(self, other):
+        if self.last_char + 1 == other.first_char and self.prop_type == other.prop_type:
+            self.last_char = other.last_char
+        else:
+            raise KeyError()
+
+    def __repr__(self):
+        types = []
+        for enum_int, enum_str in CharacterPropertyEnumMap.items():
+            if enum_int & self.prop_type:
+                types.append(enum_str)
+        return "{}0x{:04x}, 0x{:04x}, {}{}".format(
+                "{", self.first_char, self.last_char, ' | '.join(types), "}")
+
+def extract_unicode_properties(f, props):
+    prog = re.compile(r"^(?P<first>\w{4})(..(?P<last>\w{4}))?\W+;\W+(?P<prop>\w+)\n$")
+    chars = {}
+    for line in f:
+        result = prog.match(line)
+        if result:
+            prop_type_str = result.group('prop')
+            first_char_str = result.group('first')
+            last_char_str = result.group('last')
+            if prop_type_str in props:
+                start_char = int(first_char_str, 16)
+                last_char = (int(last_char_str, 16) if last_char_str else start_char) + 1
+                prop_type = props[prop_type_str]
+                for char in range(start_char, last_char):
+                    if char not in chars:
+                        chars[char] = CharacterProperty(char, char, 0)
+                    chars[char].prop_type |= prop_type
+
+    result = []
+    for char_prop in sorted(chars.values(), key=CharacterProperty.key):
+        if len(result) == 0:
+            result.append(char_prop)
+        else:
+            try:
+                result[len(result) - 1].merge(char_prop)
+            except KeyError:
+                result.append(char_prop)
+    return result
+
+license = """/*
+ * Copyright (C) 2017 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.
+ */
+"""
+
+if __name__ == "__main__":
+    if len(sys.argv) != 2:
+        print("must specify path to icu DerivedCoreProperties file (e.g:" \
+                "external/icu/icu4c/source/data/unidata/DerivedCoreProperties.txt)")
+        sys.exit(1)
+
+    with open(sys.argv[1]) as f:
+        props = {"XID_Start": 1, "XID_Continue": 2}
+        char_props = extract_unicode_properties(f, props)
+        print("{}\nconst static std::array<CharacterProperties, {}> sCharacterProperties = {}"
+                .format(license, len(char_props), "{{"))
+        for prop in char_props:
+            print("    {},".format(prop))
+        print("}};")
+
diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h
index b43f8e8..9a82418 100644
--- a/tools/aapt2/util/Maybe.h
+++ b/tools/aapt2/util/Maybe.h
@@ -281,16 +281,12 @@
   return Maybe<T>();
 }
 
-/**
- * Define the == operator between Maybe<T> and Maybe<U> only if the operator T
- * == U is defined.
- * That way the compiler will show an error at the callsite when comparing two
- * Maybe<> objects
- * whose inner types can't be compared.
- */
+// Define the == operator between Maybe<T> and Maybe<U> only if the operator T == U is defined.
+// That way the compiler will show an error at the callsite when comparing two Maybe<> objects
+// whose inner types can't be compared.
 template <typename T, typename U>
-typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator==(
-    const Maybe<T>& a, const Maybe<U>& b) {
+typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator==(const Maybe<T>& a,
+                                                                       const Maybe<U>& b) {
   if (a && b) {
     return a.value() == b.value();
   } else if (!a && !b) {
@@ -299,18 +295,22 @@
   return false;
 }
 
-/**
- * Same as operator== but negated.
- */
 template <typename T, typename U>
-typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator!=(
-    const Maybe<T>& a, const Maybe<U>& b) {
+typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator==(const Maybe<T>& a,
+                                                                       const U& b) {
+  return a ? a.value() == b : false;
+}
+
+// Same as operator== but negated.
+template <typename T, typename U>
+typename std::enable_if<has_eq_op<T, U>::value, bool>::type operator!=(const Maybe<T>& a,
+                                                                       const Maybe<U>& b) {
   return !(a == b);
 }
 
 template <typename T, typename U>
-typename std::enable_if<has_lt_op<T, U>::value, bool>::type operator<(
-    const Maybe<T>& a, const Maybe<U>& b) {
+typename std::enable_if<has_lt_op<T, U>::value, bool>::type operator<(const Maybe<T>& a,
+                                                                      const Maybe<U>& b) {
   if (a && b) {
     return a.value() < b.value();
   } else if (!a && !b) {
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp
index 28e952e..51a75d7 100644
--- a/tools/aapt2/util/Util.cpp
+++ b/tools/aapt2/util/Util.cpp
@@ -16,19 +16,21 @@
 
 #include "util/Util.h"
 
-#include <utils/Unicode.h>
 #include <algorithm>
 #include <ostream>
 #include <string>
 #include <vector>
 
 #include "androidfw/StringPiece.h"
+#include "utils/Unicode.h"
 
+#include "text/Utf8Iterator.h"
 #include "util/BigBuffer.h"
 #include "util/Maybe.h"
 
-using android::StringPiece;
-using android::StringPiece16;
+using ::aapt::text::Utf8Iterator;
+using ::android::StringPiece;
+using ::android::StringPiece16;
 
 namespace aapt {
 namespace util {
@@ -283,33 +285,49 @@
   return true;
 }
 
-static Maybe<std::string> ParseUnicodeCodepoint(const char** start,
-                                                const char* end) {
+static bool AppendCodepointToUtf8String(char32_t codepoint, std::string* output) {
+  ssize_t len = utf32_to_utf8_length(&codepoint, 1);
+  if (len < 0) {
+    return false;
+  }
+
+  const size_t start_append_pos = output->size();
+
+  // Make room for the next character.
+  output->resize(output->size() + len);
+
+  char* dst = &*(output->begin() + start_append_pos);
+  utf32_to_utf8(&codepoint, 1, dst, len + 1);
+  return true;
+}
+
+static bool AppendUnicodeCodepoint(Utf8Iterator* iter, std::string* output) {
   char32_t code = 0;
-  for (size_t i = 0; i < 4 && *start != end; i++, (*start)++) {
-    char c = **start;
+  for (size_t i = 0; i < 4 && iter->HasNext(); i++) {
+    char32_t codepoint = iter->Next();
     char32_t a;
-    if (c >= '0' && c <= '9') {
-      a = c - '0';
-    } else if (c >= 'a' && c <= 'f') {
-      a = c - 'a' + 10;
-    } else if (c >= 'A' && c <= 'F') {
-      a = c - 'A' + 10;
+    if (codepoint >= U'0' && codepoint <= U'9') {
+      a = codepoint - U'0';
+    } else if (codepoint >= U'a' && codepoint <= U'f') {
+      a = codepoint - U'a' + 10;
+    } else if (codepoint >= U'A' && codepoint <= U'F') {
+      a = codepoint - U'A' + 10;
     } else {
       return {};
     }
     code = (code << 4) | a;
   }
+  return AppendCodepointToUtf8String(code, output);
+}
 
-  ssize_t len = utf32_to_utf8_length(&code, 1);
-  if (len < 0) {
-    return {};
+static bool IsCodepointSpace(char32_t codepoint) {
+  if (static_cast<uint32_t>(codepoint) & 0xffffff00u) {
+    return false;
   }
+  return isspace(static_cast<char>(codepoint));
+}
 
-  std::string result_utf8;
-  result_utf8.resize(len);
-  utf32_to_utf8(&code, 1, &*result_utf8.begin(), len + 1);
-  return result_utf8;
+StringBuilder::StringBuilder(bool preserve_spaces) : preserve_spaces_(preserve_spaces) {
 }
 
 StringBuilder& StringBuilder::Append(const StringPiece& str) {
@@ -318,64 +336,51 @@
   }
 
   // Where the new data will be appended to.
-  size_t new_data_index = str_.size();
+  const size_t new_data_index = str_.size();
 
-  const char* const end = str.end();
-  const char* start = str.begin();
-  const char* current = start;
-  while (current != end) {
+  Utf8Iterator iter(str);
+  while (iter.HasNext()) {
+    const char32_t codepoint = iter.Next();
+
     if (last_char_was_escape_) {
-      switch (*current) {
-        case 't':
+      switch (codepoint) {
+        case U't':
           str_ += '\t';
           break;
-        case 'n':
+
+        case U'n':
           str_ += '\n';
           break;
-        case '#':
-          str_ += '#';
+
+        case U'#':
+        case U'@':
+        case U'?':
+        case U'"':
+        case U'\'':
+        case U'\\':
+          str_ += static_cast<char>(codepoint);
           break;
-        case '@':
-          str_ += '@';
-          break;
-        case '?':
-          str_ += '?';
-          break;
-        case '"':
-          str_ += '"';
-          break;
-        case '\'':
-          str_ += '\'';
-          break;
-        case '\\':
-          str_ += '\\';
-          break;
-        case 'u': {
-          current++;
-          Maybe<std::string> c = ParseUnicodeCodepoint(&current, end);
-          if (!c) {
+
+        case U'u':
+          if (!AppendUnicodeCodepoint(&iter, &str_)) {
             error_ = "invalid unicode escape sequence";
             return *this;
           }
-          str_ += c.value();
-          current -= 1;
           break;
-        }
 
         default:
-          // Ignore.
+          // Ignore the escape character and just include the codepoint.
+          AppendCodepointToUtf8String(codepoint, &str_);
           break;
       }
       last_char_was_escape_ = false;
-      start = current + 1;
-    } else if (*current == '"') {
+
+    } else if (!preserve_spaces_ && codepoint == U'"') {
       if (!quote_ && trailing_space_) {
-        // We found an opening quote, and we have
-        // trailing space, so we should append that
+        // We found an opening quote, and we have trailing space, so we should append that
         // space now.
         if (trailing_space_) {
-          // We had trailing whitespace, so
-          // replace with a single space.
+          // We had trailing whitespace, so replace with a single space.
           if (!str_.empty()) {
             str_ += ' ';
           }
@@ -383,13 +388,13 @@
         }
       }
       quote_ = !quote_;
-      str_.append(start, current - start);
-      start = current + 1;
-    } else if (*current == '\'' && !quote_) {
+
+    } else if (!preserve_spaces_ && codepoint == U'\'' && !quote_) {
       // This should be escaped.
       error_ = "unescaped apostrophe";
       return *this;
-    } else if (*current == '\\') {
+
+    } else if (codepoint == U'\\') {
       // This is an escape sequence, convert to the real value.
       if (!quote_ && trailing_space_) {
         // We had trailing whitespace, so
@@ -399,40 +404,35 @@
         }
         trailing_space_ = false;
       }
-      str_.append(start, current - start);
-      start = current + 1;
       last_char_was_escape_ = true;
-    } else if (!quote_) {
-      // This is not quoted text, so look for whitespace.
-      if (isspace(*current)) {
-        // We found whitespace, see if we have seen some
-        // before.
-        if (!trailing_space_) {
-          // We didn't see a previous adjacent space,
-          // so mark that we did.
+    } else {
+      if (preserve_spaces_ || quote_) {
+        // Quotes mean everything is taken, including whitespace.
+        AppendCodepointToUtf8String(codepoint, &str_);
+      } else {
+        // This is not quoted text, so we will accumulate whitespace and only emit a single
+        // character of whitespace if it is followed by a non-whitespace character.
+        if (IsCodepointSpace(codepoint)) {
+          // We found whitespace.
           trailing_space_ = true;
-          str_.append(start, current - start);
+        } else {
+          if (trailing_space_) {
+            // We saw trailing space before, so replace all
+            // that trailing space with one space.
+            if (!str_.empty()) {
+              str_ += ' ';
+            }
+            trailing_space_ = false;
+          }
+          AppendCodepointToUtf8String(codepoint, &str_);
         }
-
-        // Keep skipping whitespace.
-        start = current + 1;
-      } else if (trailing_space_) {
-        // We saw trailing space before, so replace all
-        // that trailing space with one space.
-        if (!str_.empty()) {
-          str_ += ' ';
-        }
-        trailing_space_ = false;
       }
     }
-    current++;
   }
-  str_.append(start, end - start);
 
   // Accumulate the added string's UTF-16 length.
-  ssize_t len = utf8_to_utf16_length(
-      reinterpret_cast<const uint8_t*>(str_.data()) + new_data_index,
-      str_.size() - new_data_index);
+  ssize_t len = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(str_.data()) + new_data_index,
+                                     str_.size() - new_data_index);
   if (len < 0) {
     error_ = "invalid unicode code point";
     return *this;
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index 8bca9dd..410258c 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -171,6 +171,8 @@
 
 class StringBuilder {
  public:
+  explicit StringBuilder(bool preserve_spaces = false);
+
   StringBuilder& Append(const android::StringPiece& str);
   const std::string& ToString() const;
   const std::string& Error() const;
@@ -184,6 +186,7 @@
   explicit operator bool() const;
 
  private:
+  bool preserve_spaces_;
   std::string str_;
   size_t utf16_len_ = 0;
   bool quote_ = false;
diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp
index a09001a..adb5291 100644
--- a/tools/aapt2/util/Util_test.cpp
+++ b/tools/aapt2/util/Util_test.cpp
@@ -20,16 +20,17 @@
 
 #include "test/Test.h"
 
-using android::StringPiece;
+using ::android::StringPiece;
+using ::testing::Eq;
+using ::testing::Ne;
+using ::testing::SizeIs;
 
 namespace aapt {
 
 TEST(UtilTest, TrimOnlyWhitespace) {
-  const std::string full = "\n        ";
-
-  StringPiece trimmed = util::TrimWhitespace(full);
+  const StringPiece trimmed = util::TrimWhitespace("\n        ");
   EXPECT_TRUE(trimmed.empty());
-  EXPECT_EQ(0u, trimmed.size());
+  EXPECT_THAT(trimmed, SizeIs(0u));
 }
 
 TEST(UtilTest, StringEndsWith) {
@@ -41,85 +42,74 @@
 }
 
 TEST(UtilTest, StringBuilderSplitEscapeSequence) {
-  EXPECT_EQ(StringPiece("this is a new\nline."), util::StringBuilder()
-                                                     .Append("this is a new\\")
-                                                     .Append("nline.")
-                                                     .ToString());
+  EXPECT_THAT(util::StringBuilder().Append("this is a new\\").Append("nline.").ToString(),
+              Eq("this is a new\nline."));
 }
 
 TEST(UtilTest, StringBuilderWhitespaceRemoval) {
-  EXPECT_EQ(StringPiece("hey guys this is so cool"),
-            util::StringBuilder()
-                .Append("    hey guys ")
-                .Append(" this is so cool ")
-                .ToString());
-
-  EXPECT_EQ(StringPiece(" wow,  so many \t spaces. what?"),
-            util::StringBuilder()
-                .Append(" \" wow,  so many \t ")
-                .Append("spaces. \"what? ")
-                .ToString());
-
-  EXPECT_EQ(StringPiece("where is the pie?"), util::StringBuilder()
-                                                  .Append("  where \t ")
-                                                  .Append(" \nis the "
-                                                          " pie?")
-                                                  .ToString());
+  EXPECT_THAT(util::StringBuilder().Append("    hey guys ").Append(" this is so cool ").ToString(),
+              Eq("hey guys this is so cool"));
+  EXPECT_THAT(
+      util::StringBuilder().Append(" \" wow,  so many \t ").Append("spaces. \"what? ").ToString(),
+      Eq(" wow,  so many \t spaces. what?"));
+  EXPECT_THAT(util::StringBuilder().Append("  where \t ").Append(" \nis the pie?").ToString(),
+              Eq("where is the pie?"));
 }
 
 TEST(UtilTest, StringBuilderEscaping) {
-  EXPECT_EQ(StringPiece("hey guys\n this \t is so\\ cool"),
-            util::StringBuilder()
-                .Append("    hey guys\\n ")
-                .Append(" this \\t is so\\\\ cool ")
-                .ToString());
-
-  EXPECT_EQ(StringPiece("@?#\\\'"),
-            util::StringBuilder().Append("\\@\\?\\#\\\\\\'").ToString());
+  EXPECT_THAT(util::StringBuilder()
+                  .Append("    hey guys\\n ")
+                  .Append(" this \\t is so\\\\ cool ")
+                  .ToString(),
+              Eq("hey guys\n this \t is so\\ cool"));
+  EXPECT_THAT(util::StringBuilder().Append("\\@\\?\\#\\\\\\'").ToString(), Eq("@?#\\\'"));
 }
 
 TEST(UtilTest, StringBuilderMisplacedQuote) {
-  util::StringBuilder builder{};
+  util::StringBuilder builder;
   EXPECT_FALSE(builder.Append("they're coming!"));
 }
 
 TEST(UtilTest, StringBuilderUnicodeCodes) {
-  EXPECT_EQ(std::string("\u00AF\u0AF0 woah"),
-            util::StringBuilder().Append("\\u00AF\\u0AF0 woah").ToString());
-
+  EXPECT_THAT(util::StringBuilder().Append("\\u00AF\\u0AF0 woah").ToString(),
+              Eq("\u00AF\u0AF0 woah"));
   EXPECT_FALSE(util::StringBuilder().Append("\\u00 yo"));
 }
 
+TEST(UtilTest, StringBuilderPreserveSpaces) {
+  EXPECT_THAT(util::StringBuilder(true /*preserve_spaces*/).Append("\"").ToString(), Eq("\""));
+}
+
 TEST(UtilTest, TokenizeInput) {
   auto tokenizer = util::Tokenize(StringPiece("this| is|the|end"), '|');
   auto iter = tokenizer.begin();
-  ASSERT_EQ(*iter, StringPiece("this"));
+  ASSERT_THAT(*iter, Eq("this"));
   ++iter;
-  ASSERT_EQ(*iter, StringPiece(" is"));
+  ASSERT_THAT(*iter, Eq(" is"));
   ++iter;
-  ASSERT_EQ(*iter, StringPiece("the"));
+  ASSERT_THAT(*iter, Eq("the"));
   ++iter;
-  ASSERT_EQ(*iter, StringPiece("end"));
+  ASSERT_THAT(*iter, Eq("end"));
   ++iter;
-  ASSERT_EQ(tokenizer.end(), iter);
+  ASSERT_THAT(iter, Eq(tokenizer.end()));
 }
 
 TEST(UtilTest, TokenizeEmptyString) {
   auto tokenizer = util::Tokenize(StringPiece(""), '|');
   auto iter = tokenizer.begin();
-  ASSERT_NE(tokenizer.end(), iter);
-  ASSERT_EQ(StringPiece(), *iter);
+  ASSERT_THAT(iter, Ne(tokenizer.end()));
+  ASSERT_THAT(*iter, Eq(StringPiece()));
   ++iter;
-  ASSERT_EQ(tokenizer.end(), iter);
+  ASSERT_THAT(iter, Eq(tokenizer.end()));
 }
 
 TEST(UtilTest, TokenizeAtEnd) {
   auto tokenizer = util::Tokenize(StringPiece("one."), '.');
   auto iter = tokenizer.begin();
-  ASSERT_EQ(*iter, StringPiece("one"));
+  ASSERT_THAT(*iter, Eq("one"));
   ++iter;
-  ASSERT_NE(iter, tokenizer.end());
-  ASSERT_EQ(*iter, StringPiece());
+  ASSERT_THAT(iter, Ne(tokenizer.end()));
+  ASSERT_THAT(*iter, Eq(StringPiece()));
 }
 
 TEST(UtilTest, IsJavaClassName) {
@@ -146,52 +136,34 @@
 }
 
 TEST(UtilTest, FullyQualifiedClassName) {
-  Maybe<std::string> res = util::GetFullyQualifiedClassName("android", ".asdf");
-  ASSERT_TRUE(res);
-  EXPECT_EQ(res.value(), "android.asdf");
-
-  res = util::GetFullyQualifiedClassName("android", ".a.b");
-  ASSERT_TRUE(res);
-  EXPECT_EQ(res.value(), "android.a.b");
-
-  res = util::GetFullyQualifiedClassName("android", "a.b");
-  ASSERT_TRUE(res);
-  EXPECT_EQ(res.value(), "a.b");
-
-  res = util::GetFullyQualifiedClassName("", "a.b");
-  ASSERT_TRUE(res);
-  EXPECT_EQ(res.value(), "a.b");
-
-  res = util::GetFullyQualifiedClassName("android", "Class");
-  ASSERT_TRUE(res);
-  EXPECT_EQ(res.value(), "android.Class");
-
-  res = util::GetFullyQualifiedClassName("", "");
-  ASSERT_FALSE(res);
-
-  res = util::GetFullyQualifiedClassName("android", "./Apple");
-  ASSERT_FALSE(res);
+  EXPECT_THAT(util::GetFullyQualifiedClassName("android", ".asdf"), Eq("android.asdf"));
+  EXPECT_THAT(util::GetFullyQualifiedClassName("android", ".a.b"), Eq("android.a.b"));
+  EXPECT_THAT(util::GetFullyQualifiedClassName("android", "a.b"), Eq("a.b"));
+  EXPECT_THAT(util::GetFullyQualifiedClassName("", "a.b"), Eq("a.b"));
+  EXPECT_THAT(util::GetFullyQualifiedClassName("android", "Class"), Eq("android.Class"));
+  EXPECT_FALSE(util::GetFullyQualifiedClassName("", ""));
+  EXPECT_FALSE(util::GetFullyQualifiedClassName("android", "./Apple"));
 }
 
 TEST(UtilTest, ExtractResourcePathComponents) {
   StringPiece prefix, entry, suffix;
   ASSERT_TRUE(util::ExtractResFilePathParts("res/xml-sw600dp/entry.xml", &prefix, &entry, &suffix));
-  EXPECT_EQ(prefix, "res/xml-sw600dp/");
-  EXPECT_EQ(entry, "entry");
-  EXPECT_EQ(suffix, ".xml");
+  EXPECT_THAT(prefix, Eq("res/xml-sw600dp/"));
+  EXPECT_THAT(entry, Eq("entry"));
+  EXPECT_THAT(suffix, Eq(".xml"));
 
   ASSERT_TRUE(util::ExtractResFilePathParts("res/xml-sw600dp/entry.9.png", &prefix, &entry, &suffix));
-  EXPECT_EQ(prefix, "res/xml-sw600dp/");
-  EXPECT_EQ(entry, "entry");
-  EXPECT_EQ(suffix, ".9.png");
+  EXPECT_THAT(prefix, Eq("res/xml-sw600dp/"));
+  EXPECT_THAT(entry, Eq("entry"));
+  EXPECT_THAT(suffix, Eq(".9.png"));
+
+  ASSERT_TRUE(util::ExtractResFilePathParts("res//.", &prefix, &entry, &suffix));
+  EXPECT_THAT(prefix, Eq("res//"));
+  EXPECT_THAT(entry, Eq(""));
+  EXPECT_THAT(suffix, Eq("."));
 
   EXPECT_FALSE(util::ExtractResFilePathParts("AndroidManifest.xml", &prefix, &entry, &suffix));
   EXPECT_FALSE(util::ExtractResFilePathParts("res/.xml", &prefix, &entry, &suffix));
-
-  ASSERT_TRUE(util::ExtractResFilePathParts("res//.", &prefix, &entry, &suffix));
-  EXPECT_EQ(prefix, "res//");
-  EXPECT_EQ(entry, "");
-  EXPECT_EQ(suffix, ".");
 }
 
 TEST(UtilTest, VerifyJavaStringFormat) {
diff --git a/tools/aapt2/xml/XmlDom_test.cpp b/tools/aapt2/xml/XmlDom_test.cpp
index c1aa10b..f0122e8 100644
--- a/tools/aapt2/xml/XmlDom_test.cpp
+++ b/tools/aapt2/xml/XmlDom_test.cpp
@@ -21,7 +21,9 @@
 
 #include "test/Test.h"
 
+using ::testing::Eq;
 using ::testing::NotNull;
+using ::testing::SizeIs;
 
 namespace aapt {
 
@@ -30,47 +32,59 @@
 
 TEST(XmlDomTest, Inflate) {
   std::stringstream in(kXmlPreamble);
-  in << R"EOF(
-        <Layout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-            <TextView android:id="@+id/id"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content" />
-        </Layout>
-    )EOF";
+  in << R"(
+      <Layout xmlns:android="http://schemas.android.com/apk/res/android"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content">
+        <TextView android:id="@+id/id"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+      </Layout>)";
 
-  const Source source = {"test.xml"};
+  const Source source("test.xml");
   StdErrDiagnostics diag;
   std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, source);
   ASSERT_THAT(doc, NotNull());
 
   xml::Namespace* ns = xml::NodeCast<xml::Namespace>(doc->root.get());
   ASSERT_THAT(ns, NotNull());
-  EXPECT_EQ(ns->namespace_uri, xml::kSchemaAndroid);
-  EXPECT_EQ(ns->namespace_prefix, "android");
+  EXPECT_THAT(ns->namespace_uri, Eq(xml::kSchemaAndroid));
+  EXPECT_THAT(ns->namespace_prefix, Eq("android"));
 }
 
 // Escaping is handled after parsing of the values for resource-specific values.
 TEST(XmlDomTest, ForwardEscapes) {
-  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF(
-      <element value="\?hello" pattern="\\d{5}">\\d{5}</element>)EOF");
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <element value="\?hello" pattern="\\d{5}">\\d{5}</element>)");
 
-  xml::Element* el = xml::FindRootElement(doc->root.get());
+  xml::Element* el = xml::FindRootElement(doc.get());
   ASSERT_THAT(el, NotNull());
 
   xml::Attribute* attr = el->FindAttribute({}, "pattern");
   ASSERT_THAT(attr, NotNull());
-  EXPECT_EQ("\\\\d{5}", attr->value);
+  EXPECT_THAT(attr->value, Eq("\\\\d{5}"));
 
   attr = el->FindAttribute({}, "value");
   ASSERT_THAT(attr, NotNull());
-  EXPECT_EQ("\\?hello", attr->value);
+  EXPECT_THAT(attr->value, Eq("\\?hello"));
 
-  ASSERT_EQ(1u, el->children.size());
+  ASSERT_THAT(el->children, SizeIs(1u));
+
   xml::Text* text = xml::NodeCast<xml::Text>(el->children[0].get());
   ASSERT_THAT(text, NotNull());
-  EXPECT_EQ("\\\\d{5}", text->text);
+  EXPECT_THAT(text->text, Eq("\\\\d{5}"));
+}
+
+TEST(XmlDomTest, XmlEscapeSequencesAreParsed) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element value="&quot;" />)");
+
+  xml::Element* el = xml::FindRootElement(doc.get());
+  ASSERT_THAT(el, NotNull());
+
+  xml::Attribute* attr = el->FindAttribute({}, "value");
+  ASSERT_THAT(attr, NotNull());
+
+  EXPECT_THAT(attr->value, Eq("\""));
 }
 
 }  // namespace aapt
diff --git a/tools/bit/adb.cpp b/tools/bit/adb.cpp
index 0c8424d..c8faf5c 100644
--- a/tools/bit/adb.cpp
+++ b/tools/bit/adb.cpp
@@ -283,10 +283,19 @@
     cmd.AddArg("instrument");
     cmd.AddArg("-w");
     cmd.AddArg("-m");
-    if (className.length() > 0) {
-        cmd.AddArg("-e");
-        cmd.AddArg("class");
-        cmd.AddArg(className);
+    const int classLen = className.length();
+    if (classLen > 0) {
+        if (classLen > 1 && className[classLen - 1] == '.') {
+            cmd.AddArg("-e");
+            cmd.AddArg("package");
+
+            // "am" actually accepts without removing the last ".", but for cleanlines...
+            cmd.AddArg(className.substr(0, classLen - 1));
+        } else {
+            cmd.AddArg("-e");
+            cmd.AddArg("class");
+            cmd.AddArg(className);
+        }
     }
     cmd.AddArg(packageName + "/" + runner);
 
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
index d056ba5..a7fbc2e 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -342,6 +342,10 @@
     fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the testWrite\n");
     fprintf(out, "      and testRepeated test methods on that class.\n");
     fprintf(out, "\n");
+    fprintf(out, "    bit CtsProtoTestCases:android.util.proto.cts.\n");
+    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the tests in the java package\n");
+    fprintf(out, "      \"android.util.proto.cts\".\n");
+    fprintf(out, "\n");
     fprintf(out, "  Launching an Activity\n");
     fprintf(out, "  ---------------------\n");
     fprintf(out, "  To launch an activity, specify the activity class name after\n");
@@ -731,7 +735,7 @@
             InstallApk& apk = installApks[i];
             if (!apk.file.fileInfo.exists || apk.file.HasChanged()) {
                 // It didn't exist before or it changed, so int needs install
-                err = run_adb("install", "-r", apk.file.filename.c_str(), NULL);
+                err = run_adb("install", "-r", "-g", apk.file.filename.c_str(), NULL);
                 check_error(err);
                 apk.installed = true;
             } else {
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index 06e3867..357f76e 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -82,7 +82,7 @@
         mClientId = clientId;
         mSessionId = sessionId;
 
-        mCloseGuard.open("destroy");
+        mCloseGuard.open("close");
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 428c8bb..f26b9f5 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -54,7 +54,7 @@
         mClientId = clientId;
         mTerminated = false;
 
-        mCloseGuard.open("destroy");
+        mCloseGuard.open("close");
     }
 
     /**